Make sure dllname doesn't get optimized out (spotted by Marcus
[wine/testsucceed.git] / objects / font.c
blob3b5041767b68539c742d48da83e9c96a4ece6d6c
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
6 * Copyright 2002,2003 Shachar Shemesh
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "config.h"
24 #include "wine/port.h"
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include "winerror.h"
30 #include "winnls.h"
31 #include "wownt32.h"
32 #include "gdi.h"
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(font);
37 WINE_DECLARE_DEBUG_CHANNEL(gdi);
39 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
40 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
43 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
45 static const struct gdi_obj_funcs font_funcs =
47 FONT_SelectObject, /* pSelectObject */
48 FONT_GetObject16, /* pGetObject16 */
49 FONT_GetObjectA, /* pGetObjectA */
50 FONT_GetObjectW, /* pGetObjectW */
51 NULL, /* pUnrealizeObject */
52 FONT_DeleteObject /* pDeleteObject */
55 #define ENUM_UNICODE 0x00000001
56 #define ENUM_CALLED 0x00000002
58 typedef struct
60 GDIOBJHDR header;
61 LOGFONTW logfont;
62 } FONTOBJ;
64 typedef struct
66 LPLOGFONT16 lpLogFontParam;
67 FONTENUMPROC16 lpEnumFunc;
68 LPARAM lpData;
70 LPNEWTEXTMETRICEX16 lpTextMetric;
71 LPENUMLOGFONTEX16 lpLogFont;
72 SEGPTR segTextMetric;
73 SEGPTR segLogFont;
74 DWORD dwFlags;
75 HDC hdc;
76 DC *dc;
77 PHYSDEV physDev;
78 } fontEnum16;
80 typedef struct
82 LPLOGFONTW lpLogFontParam;
83 FONTENUMPROCW lpEnumFunc;
84 LPARAM lpData;
85 DWORD dwFlags;
86 HDC hdc;
87 DC *dc;
88 PHYSDEV physDev;
89 } fontEnum32;
92 * For TranslateCharsetInfo
94 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
95 #define MAXTCIINDEX 32
96 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
97 /* ANSI */
98 { ANSI_CHARSET, 1252, FS(0)},
99 { EASTEUROPE_CHARSET, 1250, FS(1)},
100 { RUSSIAN_CHARSET, 1251, FS(2)},
101 { GREEK_CHARSET, 1253, FS(3)},
102 { TURKISH_CHARSET, 1254, FS(4)},
103 { HEBREW_CHARSET, 1255, FS(5)},
104 { ARABIC_CHARSET, 1256, FS(6)},
105 { BALTIC_CHARSET, 1257, FS(7)},
106 { VIETNAMESE_CHARSET, 1258, FS(8)},
107 /* reserved by ANSI */
108 { DEFAULT_CHARSET, 0, FS(0)},
109 { DEFAULT_CHARSET, 0, FS(0)},
110 { DEFAULT_CHARSET, 0, FS(0)},
111 { DEFAULT_CHARSET, 0, FS(0)},
112 { DEFAULT_CHARSET, 0, FS(0)},
113 { DEFAULT_CHARSET, 0, FS(0)},
114 { DEFAULT_CHARSET, 0, FS(0)},
115 /* ANSI and OEM */
116 { THAI_CHARSET, 874, FS(16)},
117 { SHIFTJIS_CHARSET, 932, FS(17)},
118 { GB2312_CHARSET, 936, FS(18)},
119 { HANGEUL_CHARSET, 949, FS(19)},
120 { CHINESEBIG5_CHARSET, 950, FS(20)},
121 { JOHAB_CHARSET, 1361, FS(21)},
122 /* reserved for alternate ANSI and OEM */
123 { DEFAULT_CHARSET, 0, FS(0)},
124 { DEFAULT_CHARSET, 0, FS(0)},
125 { DEFAULT_CHARSET, 0, FS(0)},
126 { DEFAULT_CHARSET, 0, FS(0)},
127 { DEFAULT_CHARSET, 0, FS(0)},
128 { DEFAULT_CHARSET, 0, FS(0)},
129 { DEFAULT_CHARSET, 0, FS(0)},
130 { DEFAULT_CHARSET, 0, FS(0)},
131 /* reserved for system */
132 { DEFAULT_CHARSET, 0, FS(0)},
133 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
136 /***********************************************************************
137 * LOGFONT conversion functions.
139 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
141 font16->lfHeight = font32->lfHeight;
142 font16->lfWidth = font32->lfWidth;
143 font16->lfEscapement = font32->lfEscapement;
144 font16->lfOrientation = font32->lfOrientation;
145 font16->lfWeight = font32->lfWeight;
146 font16->lfItalic = font32->lfItalic;
147 font16->lfUnderline = font32->lfUnderline;
148 font16->lfStrikeOut = font32->lfStrikeOut;
149 font16->lfCharSet = font32->lfCharSet;
150 font16->lfOutPrecision = font32->lfOutPrecision;
151 font16->lfClipPrecision = font32->lfClipPrecision;
152 font16->lfQuality = font32->lfQuality;
153 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
154 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
155 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
156 font16->lfFaceName[LF_FACESIZE-1] = 0;
159 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
161 font32->lfHeight = font16->lfHeight;
162 font32->lfWidth = font16->lfWidth;
163 font32->lfEscapement = font16->lfEscapement;
164 font32->lfOrientation = font16->lfOrientation;
165 font32->lfWeight = font16->lfWeight;
166 font32->lfItalic = font16->lfItalic;
167 font32->lfUnderline = font16->lfUnderline;
168 font32->lfStrikeOut = font16->lfStrikeOut;
169 font32->lfCharSet = font16->lfCharSet;
170 font32->lfOutPrecision = font16->lfOutPrecision;
171 font32->lfClipPrecision = font16->lfClipPrecision;
172 font32->lfQuality = font16->lfQuality;
173 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
174 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
175 font32->lfFaceName[LF_FACESIZE-1] = 0;
178 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
180 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
181 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
182 LF_FACESIZE);
185 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
187 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
188 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
189 LF_FACESIZE, NULL, NULL);
192 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
194 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
196 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
197 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
198 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
199 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
200 font16->elfStyle, LF_FACESIZE, NULL, NULL );
201 font16->elfStyle[LF_FACESIZE-1] = '\0';
202 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
203 font16->elfScript, LF_FACESIZE, NULL, NULL );
204 font16->elfScript[LF_FACESIZE-1] = '\0';
207 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
209 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
211 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
212 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
213 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
214 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
215 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
216 fontA->elfStyle[LF_FACESIZE-1] = '\0';
217 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
218 fontA->elfScript, LF_FACESIZE, NULL, NULL );
219 fontA->elfScript[LF_FACESIZE-1] = '\0';
222 /***********************************************************************
223 * TEXTMETRIC conversion functions.
225 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
227 ptmA->tmHeight = ptmW->tmHeight;
228 ptmA->tmAscent = ptmW->tmAscent;
229 ptmA->tmDescent = ptmW->tmDescent;
230 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
231 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
232 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
233 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
234 ptmA->tmWeight = ptmW->tmWeight;
235 ptmA->tmOverhang = ptmW->tmOverhang;
236 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
237 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
238 ptmA->tmFirstChar = ptmW->tmFirstChar;
239 ptmA->tmLastChar = ptmW->tmLastChar;
240 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
241 ptmA->tmBreakChar = ptmW->tmBreakChar;
242 ptmA->tmItalic = ptmW->tmItalic;
243 ptmA->tmUnderlined = ptmW->tmUnderlined;
244 ptmA->tmStruckOut = ptmW->tmStruckOut;
245 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
246 ptmA->tmCharSet = ptmW->tmCharSet;
250 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
252 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
253 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
254 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
255 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
256 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
257 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
258 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
259 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
260 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
261 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
262 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
263 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
264 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
265 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
266 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
267 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
268 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
269 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
270 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
271 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
272 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
273 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
274 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
275 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
276 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
279 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
281 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
282 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
283 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
284 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
285 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
286 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
289 /***********************************************************************
290 * CreateFontIndirectA (GDI32.@)
292 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
294 LOGFONTW lfW;
296 if (plfA) {
297 FONT_LogFontAToW( plfA, &lfW );
298 return CreateFontIndirectW( &lfW );
299 } else
300 return CreateFontIndirectW( NULL );
304 /***********************************************************************
305 * CreateFontIndirectW (GDI32.@)
307 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
309 HFONT hFont = 0;
311 if (plf)
313 FONTOBJ* fontPtr;
314 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
315 (HGDIOBJ *)&hFont, &font_funcs )))
317 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
319 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
320 plf->lfHeight, plf->lfWidth,
321 plf->lfEscapement, plf->lfOrientation,
322 plf->lfPitchAndFamily,
323 plf->lfOutPrecision, plf->lfClipPrecision,
324 plf->lfQuality, plf->lfCharSet,
325 debugstr_w(plf->lfFaceName),
326 plf->lfWeight > 400 ? "Bold" : "",
327 plf->lfItalic ? "Italic" : "", hFont);
329 if (plf->lfEscapement != plf->lfOrientation) {
330 /* this should really depend on whether GM_ADVANCED is set */
331 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
332 WARN("orientation angle %f set to "
333 "escapement angle %f for new font %p\n",
334 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
336 GDI_ReleaseObj( hFont );
339 else WARN("(NULL) => NULL\n");
341 return hFont;
344 /*************************************************************************
345 * CreateFontA (GDI32.@)
347 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
348 INT orient, INT weight, DWORD italic,
349 DWORD underline, DWORD strikeout, DWORD charset,
350 DWORD outpres, DWORD clippres, DWORD quality,
351 DWORD pitch, LPCSTR name )
353 LOGFONTA logfont;
355 logfont.lfHeight = height;
356 logfont.lfWidth = width;
357 logfont.lfEscapement = esc;
358 logfont.lfOrientation = orient;
359 logfont.lfWeight = weight;
360 logfont.lfItalic = italic;
361 logfont.lfUnderline = underline;
362 logfont.lfStrikeOut = strikeout;
363 logfont.lfCharSet = charset;
364 logfont.lfOutPrecision = outpres;
365 logfont.lfClipPrecision = clippres;
366 logfont.lfQuality = quality;
367 logfont.lfPitchAndFamily = pitch;
369 if (name)
370 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
371 else
372 logfont.lfFaceName[0] = '\0';
374 return CreateFontIndirectA( &logfont );
377 /*************************************************************************
378 * CreateFontW (GDI32.@)
380 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
381 INT orient, INT weight, DWORD italic,
382 DWORD underline, DWORD strikeout, DWORD charset,
383 DWORD outpres, DWORD clippres, DWORD quality,
384 DWORD pitch, LPCWSTR name )
386 LOGFONTW logfont;
388 logfont.lfHeight = height;
389 logfont.lfWidth = width;
390 logfont.lfEscapement = esc;
391 logfont.lfOrientation = orient;
392 logfont.lfWeight = weight;
393 logfont.lfItalic = italic;
394 logfont.lfUnderline = underline;
395 logfont.lfStrikeOut = strikeout;
396 logfont.lfCharSet = charset;
397 logfont.lfOutPrecision = outpres;
398 logfont.lfClipPrecision = clippres;
399 logfont.lfQuality = quality;
400 logfont.lfPitchAndFamily = pitch;
402 if (name)
403 lstrcpynW(logfont.lfFaceName, name,
404 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
405 else
406 logfont.lfFaceName[0] = '\0';
408 return CreateFontIndirectW( &logfont );
412 /***********************************************************************
413 * FONT_SelectObject
415 * If the driver supports vector fonts we create a gdi font first and
416 * then call the driver to give it a chance to supply its own device
417 * font. If the driver wants to do this it returns TRUE and we can
418 * delete the gdi font, if the driver wants to use the gdi font it
419 * should return FALSE, to signal an error return GDI_ERROR. For
420 * drivers that don't support vector fonts they must supply their own
421 * font.
423 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
425 HGDIOBJ ret = 0;
426 DC *dc = DC_GetDCPtr( hdc );
428 if (!dc) return 0;
430 if (dc->hFont != handle || dc->gdiFont == NULL)
432 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
433 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
436 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
438 if (ret && dc->gdiFont) dc->gdiFont = 0;
440 if (ret == HGDI_ERROR)
441 ret = 0; /* SelectObject returns 0 on error */
442 else
444 ret = dc->hFont;
445 dc->hFont = handle;
447 GDI_ReleaseObj( hdc );
448 return ret;
452 /***********************************************************************
453 * FONT_GetObject16
455 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
457 FONTOBJ *font = obj;
458 LOGFONT16 lf16;
460 FONT_LogFontWTo16( &font->logfont, &lf16 );
462 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
463 memcpy( buffer, &lf16, count );
464 return count;
467 /***********************************************************************
468 * FONT_GetObjectA
470 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
472 FONTOBJ *font = obj;
473 LOGFONTA lfA;
475 if(!buffer)
476 return sizeof(lfA);
477 FONT_LogFontWToA( &font->logfont, &lfA );
479 if (count > sizeof(lfA)) count = sizeof(lfA);
480 memcpy( buffer, &lfA, count );
481 return count;
484 /***********************************************************************
485 * FONT_GetObjectW
487 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
489 FONTOBJ *font = obj;
490 if(!buffer)
491 return sizeof(LOGFONTW);
492 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
493 memcpy( buffer, &font->logfont, count );
494 return count;
498 /***********************************************************************
499 * FONT_DeleteObject
501 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
503 WineEngDestroyFontInstance( handle );
504 return GDI_FreeObject( handle, obj );
508 /***********************************************************************
509 * FONT_EnumInstance16
511 * Called by the device driver layer to pass font info
512 * down to the application.
514 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
515 DWORD fType, LPARAM lp )
517 fontEnum16 *pfe = (fontEnum16*)lp;
518 INT ret = 1;
519 DC *dc;
521 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
522 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
524 WORD args[7];
525 DWORD result;
527 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
528 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
529 pfe->dwFlags |= ENUM_CALLED;
530 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
532 args[6] = SELECTOROF(pfe->segLogFont);
533 args[5] = OFFSETOF(pfe->segLogFont);
534 args[4] = SELECTOROF(pfe->segTextMetric);
535 args[3] = OFFSETOF(pfe->segTextMetric);
536 args[2] = fType;
537 args[1] = HIWORD(pfe->lpData);
538 args[0] = LOWORD(pfe->lpData);
539 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
540 ret = LOWORD(result);
542 /* get the lock again and make sure the DC is still valid */
543 dc = DC_GetDCPtr( pfe->hdc );
544 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
546 if (dc) GDI_ReleaseObj( pfe->hdc );
547 pfe->hdc = 0; /* make sure we don't try to release it later on */
548 ret = 0;
551 return ret;
554 /***********************************************************************
555 * FONT_EnumInstance
557 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
558 DWORD fType, LPARAM lp )
560 fontEnum32 *pfe = (fontEnum32*)lp;
561 INT ret = 1;
562 DC *dc;
564 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
565 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
566 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
568 /* convert font metrics */
569 ENUMLOGFONTEXA logfont;
570 NEWTEXTMETRICEXA tmA;
572 pfe->dwFlags |= ENUM_CALLED;
573 if (!(pfe->dwFlags & ENUM_UNICODE))
575 FONT_EnumLogFontExWToA( plf, &logfont);
576 FONT_NewTextMetricExWToA( ptm, &tmA );
577 plf = (LPENUMLOGFONTEXW)&logfont;
578 ptm = (NEWTEXTMETRICEXW *)&tmA;
580 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
582 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
584 /* get the lock again and make sure the DC is still valid */
585 dc = DC_GetDCPtr( pfe->hdc );
586 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
588 if (dc) GDI_ReleaseObj( pfe->hdc );
589 pfe->hdc = 0; /* make sure we don't try to release it later on */
590 ret = 0;
593 return ret;
596 /***********************************************************************
597 * EnumFontFamiliesEx (GDI.613)
599 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
600 FONTENUMPROC16 efproc, LPARAM lParam,
601 DWORD dwFlags)
603 fontEnum16 fe16;
604 INT16 ret = 1, ret2;
605 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
606 NEWTEXTMETRICEX16 tm16;
607 ENUMLOGFONTEX16 lf16;
608 LOGFONTW lfW;
609 BOOL enum_gdi_fonts;
611 if (!dc) return 0;
612 FONT_LogFont16ToW(plf, &lfW);
614 fe16.hdc = HDC_32(hDC);
615 fe16.dc = dc;
616 fe16.physDev = dc->physDev;
617 fe16.lpLogFontParam = plf;
618 fe16.lpEnumFunc = efproc;
619 fe16.lpData = lParam;
620 fe16.lpTextMetric = &tm16;
621 fe16.lpLogFont = &lf16;
622 fe16.segTextMetric = MapLS( &tm16 );
623 fe16.segLogFont = MapLS( &lf16 );
624 fe16.dwFlags = 0;
626 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
628 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
630 ret = 0;
631 goto done;
634 if (enum_gdi_fonts)
635 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
636 fe16.dwFlags &= ~ENUM_CALLED;
637 if (ret && dc->funcs->pEnumDeviceFonts) {
638 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
639 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
640 ret = ret2;
642 done:
643 UnMapLS( fe16.segTextMetric );
644 UnMapLS( fe16.segLogFont );
645 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
646 return ret;
649 /***********************************************************************
650 * FONT_EnumFontFamiliesEx
652 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
653 FONTENUMPROCW efproc,
654 LPARAM lParam, DWORD dwUnicode)
656 INT ret = 1, ret2;
657 DC *dc = DC_GetDCPtr( hDC );
658 fontEnum32 fe32;
659 BOOL enum_gdi_fonts;
661 if (!dc) return 0;
663 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
664 plf->lfCharSet);
665 fe32.lpLogFontParam = plf;
666 fe32.lpEnumFunc = efproc;
667 fe32.lpData = lParam;
668 fe32.dwFlags = dwUnicode;
669 fe32.hdc = hDC;
670 fe32.dc = dc;
671 fe32.physDev = dc->physDev;
673 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
675 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
677 ret = 0;
678 goto done;
681 if (enum_gdi_fonts)
682 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
683 fe32.dwFlags &= ~ENUM_CALLED;
684 if (ret && dc->funcs->pEnumDeviceFonts) {
685 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
686 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
687 ret = ret2;
689 done:
690 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
691 return ret;
694 /***********************************************************************
695 * EnumFontFamiliesExW (GDI32.@)
697 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
698 FONTENUMPROCW efproc,
699 LPARAM lParam, DWORD dwFlags )
701 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
704 /***********************************************************************
705 * EnumFontFamiliesExA (GDI32.@)
707 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
708 FONTENUMPROCA efproc,
709 LPARAM lParam, DWORD dwFlags)
711 LOGFONTW lfW;
712 FONT_LogFontAToW( plf, &lfW );
714 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
717 /***********************************************************************
718 * EnumFontFamilies (GDI.330)
720 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
721 FONTENUMPROC16 efproc, LPARAM lpData )
723 LOGFONT16 lf;
725 lf.lfCharSet = DEFAULT_CHARSET;
726 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
727 else lf.lfFaceName[0] = '\0';
729 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
732 /***********************************************************************
733 * EnumFontFamiliesA (GDI32.@)
735 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
736 FONTENUMPROCA efproc, LPARAM lpData )
738 LOGFONTA lf;
740 lf.lfCharSet = DEFAULT_CHARSET;
741 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
742 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
744 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
747 /***********************************************************************
748 * EnumFontFamiliesW (GDI32.@)
750 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
751 FONTENUMPROCW efproc, LPARAM lpData )
753 LOGFONTW lf;
755 lf.lfCharSet = DEFAULT_CHARSET;
756 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
757 else lf.lfFaceName[0] = 0;
759 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
762 /***********************************************************************
763 * EnumFonts (GDI.70)
765 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
766 LPARAM lpData )
768 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
771 /***********************************************************************
772 * EnumFontsA (GDI32.@)
774 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
775 LPARAM lpData )
777 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
780 /***********************************************************************
781 * EnumFontsW (GDI32.@)
783 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
784 LPARAM lpData )
786 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
790 /***********************************************************************
791 * GetTextCharacterExtra (GDI32.@)
793 INT WINAPI GetTextCharacterExtra( HDC hdc )
795 INT ret;
796 DC *dc = DC_GetDCPtr( hdc );
797 if (!dc) return 0x80000000;
798 ret = dc->charExtra;
799 GDI_ReleaseObj( hdc );
800 return ret;
804 /***********************************************************************
805 * SetTextCharacterExtra (GDI32.@)
807 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
809 INT prev;
810 DC * dc = DC_GetDCPtr( hdc );
811 if (!dc) return 0x80000000;
812 if (dc->funcs->pSetTextCharacterExtra)
813 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
814 else
816 prev = dc->charExtra;
817 dc->charExtra = extra;
819 GDI_ReleaseObj( hdc );
820 return prev;
824 /***********************************************************************
825 * SetTextJustification (GDI32.@)
827 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
829 BOOL ret = TRUE;
830 DC * dc = DC_GetDCPtr( hdc );
831 if (!dc) return FALSE;
832 if (dc->funcs->pSetTextJustification)
833 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
834 else
836 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
837 if (!extra) breaks = 0;
838 dc->breakTotalExtra = extra;
839 dc->breakCount = breaks;
840 if (breaks)
842 dc->breakExtra = extra / breaks;
843 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
845 else
847 dc->breakExtra = 0;
848 dc->breakRem = 0;
851 GDI_ReleaseObj( hdc );
852 return ret;
856 /***********************************************************************
857 * GetTextFaceA (GDI32.@)
859 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
861 INT res = GetTextFaceW(hdc, 0, NULL);
862 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
863 GetTextFaceW( hdc, res, nameW );
865 if (name)
867 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
868 name[count-1] = 0;
869 res = strlen(name);
871 else
872 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
873 HeapFree( GetProcessHeap(), 0, nameW );
874 return res;
877 /***********************************************************************
878 * GetTextFaceW (GDI32.@)
880 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
882 FONTOBJ *font;
883 INT ret = 0;
885 DC * dc = DC_GetDCPtr( hdc );
886 if (!dc) return 0;
888 if(dc->gdiFont)
889 ret = WineEngGetTextFace(dc->gdiFont, count, name);
890 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
892 if (name)
894 lstrcpynW( name, font->logfont.lfFaceName, count );
895 ret = strlenW(name);
897 else ret = strlenW(font->logfont.lfFaceName) + 1;
898 GDI_ReleaseObj( dc->hFont );
900 GDI_ReleaseObj( hdc );
901 return ret;
905 /***********************************************************************
906 * GetTextExtentPoint32A (GDI32.@)
908 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
909 LPSIZE size )
911 BOOL ret = FALSE;
912 INT wlen;
913 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
915 if (p) {
916 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
917 HeapFree( GetProcessHeap(), 0, p );
920 TRACE("(%p %s %d %p): returning %ld x %ld\n",
921 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
922 return ret;
926 /***********************************************************************
927 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
929 * Computes width and height of the specified string.
931 * RETURNS
932 * Success: TRUE
933 * Failure: FALSE
935 BOOL WINAPI GetTextExtentPoint32W(
936 HDC hdc, /* [in] Handle of device context */
937 LPCWSTR str, /* [in] Address of text string */
938 INT count, /* [in] Number of characters in string */
939 LPSIZE size) /* [out] Address of structure for string size */
941 BOOL ret = FALSE;
942 DC * dc = DC_GetDCPtr( hdc );
943 if (!dc) return FALSE;
945 if(dc->gdiFont) {
946 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
947 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
948 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
950 else if(dc->funcs->pGetTextExtentPoint)
951 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
953 GDI_ReleaseObj( hdc );
955 TRACE("(%p %s %d %p): returning %ld x %ld\n",
956 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
957 return ret;
960 /***********************************************************************
961 * GetTextExtentPointI [GDI32.@]
963 * Computes width and height of the array of glyph indices.
965 * RETURNS
966 * Success: TRUE
967 * Failure: FALSE
969 BOOL WINAPI GetTextExtentPointI(
970 HDC hdc, /* [in] Handle of device context */
971 const WORD *indices, /* [in] Address of glyph index array */
972 INT count, /* [in] Number of glyphs in array */
973 LPSIZE size) /* [out] Address of structure for string size */
975 BOOL ret = FALSE;
976 DC * dc = DC_GetDCPtr( hdc );
977 if (!dc) return FALSE;
979 if(dc->gdiFont) {
980 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
981 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
982 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
984 else if(dc->funcs->pGetTextExtentPoint) {
985 FIXME("calling GetTextExtentPoint\n");
986 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
989 GDI_ReleaseObj( hdc );
991 TRACE("(%p %p %d %p): returning %ld x %ld\n",
992 hdc, indices, count, size, size->cx, size->cy );
993 return ret;
997 /***********************************************************************
998 * GetTextExtentPointA (GDI32.@)
1000 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1001 LPSIZE size )
1003 TRACE("not bug compatible.\n");
1004 return GetTextExtentPoint32A( hdc, str, count, size );
1007 /***********************************************************************
1008 * GetTextExtentPointW (GDI32.@)
1010 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1011 LPSIZE size )
1013 TRACE("not bug compatible.\n");
1014 return GetTextExtentPoint32W( hdc, str, count, size );
1018 /***********************************************************************
1019 * GetTextExtentExPointA (GDI32.@)
1021 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1022 INT maxExt, LPINT lpnFit,
1023 LPINT alpDx, LPSIZE size )
1025 BOOL ret;
1026 INT wlen;
1027 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1028 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1029 HeapFree( GetProcessHeap(), 0, p );
1030 return ret;
1034 /***********************************************************************
1035 * GetTextExtentExPointW (GDI32.@)
1037 * Return the size of the string as it would be if it was output properly by
1038 * e.g. TextOut.
1040 * This should include
1041 * - Intercharacter spacing
1042 * - justification spacing (not yet done)
1043 * - kerning? see below
1045 * Kerning. Since kerning would be carried out by the rendering code it should
1046 * be done by the driver. However they don't support it yet. Also I am not
1047 * yet persuaded that (certainly under Win95) any kerning is actually done.
1049 * str: According to MSDN this should be null-terminated. That is not true; a
1050 * null will not terminate it early.
1051 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1052 * than count. I have seen it be either the size of the full string or
1053 * 1 less than the size of the full string. I have not seen it bear any
1054 * resemblance to the portion that would fit.
1055 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1056 * trailing intercharacter spacing and any trailing justification.
1058 * FIXME
1059 * Currently we do this by measuring each character etc. We should do it by
1060 * passing the request to the driver, perhaps by extending the
1061 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1062 * thinking about kerning issues and rounding issues in the justification.
1065 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1066 INT maxExt, LPINT lpnFit,
1067 LPINT alpDx, LPSIZE size )
1069 int index, nFit, extent;
1070 SIZE tSize;
1071 BOOL ret = FALSE;
1073 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1075 size->cx = size->cy = nFit = extent = 0;
1076 for(index = 0; index < count; index++)
1078 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1079 /* GetTextExtentPoint includes intercharacter spacing. */
1080 /* FIXME - justification needs doing yet. Remember that the base
1081 * data will not be in logical coordinates.
1083 extent += tSize.cx;
1084 if( !lpnFit || extent <= maxExt )
1085 /* It is allowed to be equal. */
1087 nFit++;
1088 if( alpDx ) alpDx[index] = extent;
1090 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1091 str++;
1093 size->cx = extent;
1094 if(lpnFit) *lpnFit = nFit;
1095 ret = TRUE;
1097 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1099 done:
1100 return ret;
1103 /***********************************************************************
1104 * GetTextMetricsA (GDI32.@)
1106 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1108 TEXTMETRICW tm32;
1110 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1111 FONT_TextMetricWToA( &tm32, metrics );
1112 return TRUE;
1115 /***********************************************************************
1116 * GetTextMetricsW (GDI32.@)
1118 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1120 BOOL ret = FALSE;
1121 DC * dc = DC_GetDCPtr( hdc );
1122 if (!dc) return FALSE;
1124 if (dc->gdiFont)
1125 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1126 else if (dc->funcs->pGetTextMetrics)
1127 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1129 if (ret)
1131 /* device layer returns values in device units
1132 * therefore we have to convert them to logical */
1134 #define WDPTOLP(x) ((x<0)? \
1135 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1136 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1137 #define HDPTOLP(y) ((y<0)? \
1138 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1139 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1141 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1142 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1143 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1144 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1145 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1146 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1147 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1148 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1149 ret = TRUE;
1150 #undef WDPTOLP
1151 #undef HDPTOLP
1152 TRACE("text metrics:\n"
1153 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1154 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1155 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1156 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1157 " PitchAndFamily = %02x\n"
1158 " --------------------\n"
1159 " InternalLeading = %li\n"
1160 " Ascent = %li\n"
1161 " Descent = %li\n"
1162 " Height = %li\n",
1163 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1164 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1165 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1166 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1167 metrics->tmPitchAndFamily,
1168 metrics->tmInternalLeading,
1169 metrics->tmAscent,
1170 metrics->tmDescent,
1171 metrics->tmHeight );
1173 GDI_ReleaseObj( hdc );
1174 return ret;
1178 /***********************************************************************
1179 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1181 * NOTES
1182 * lpOTM should be LPOUTLINETEXTMETRIC
1184 * RETURNS
1185 * Success: Non-zero or size of required buffer
1186 * Failure: 0
1188 UINT16 WINAPI GetOutlineTextMetrics16(
1189 HDC16 hdc, /* [in] Handle of device context */
1190 UINT16 cbData, /* [in] Size of metric data array */
1191 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1193 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1194 return 0;
1198 /***********************************************************************
1199 * GetOutlineTextMetricsA (GDI32.@)
1200 * Gets metrics for TrueType fonts.
1203 * RETURNS
1204 * Success: Non-zero or size of required buffer
1205 * Failure: 0
1207 UINT WINAPI GetOutlineTextMetricsA(
1208 HDC hdc, /* [in] Handle of device context */
1209 UINT cbData, /* [in] Size of metric data array */
1210 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1212 char buf[512], *ptr;
1213 UINT ret, needed;
1214 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1215 INT left, len;
1217 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1218 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1219 return 0;
1220 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1221 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1224 needed = sizeof(OUTLINETEXTMETRICA);
1225 if(lpOTMW->otmpFamilyName)
1226 needed += WideCharToMultiByte(CP_ACP, 0,
1227 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1228 NULL, 0, NULL, NULL);
1229 if(lpOTMW->otmpFaceName)
1230 needed += WideCharToMultiByte(CP_ACP, 0,
1231 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1232 NULL, 0, NULL, NULL);
1233 if(lpOTMW->otmpStyleName)
1234 needed += WideCharToMultiByte(CP_ACP, 0,
1235 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1236 NULL, 0, NULL, NULL);
1237 if(lpOTMW->otmpFullName)
1238 needed += WideCharToMultiByte(CP_ACP, 0,
1239 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1240 NULL, 0, NULL, NULL);
1242 if(!lpOTM) {
1243 ret = needed;
1244 goto end;
1247 if(needed > cbData) {
1248 ret = 0;
1249 goto end;
1253 lpOTM->otmSize = needed;
1254 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1255 lpOTM->otmFiller = 0;
1256 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1257 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1258 lpOTM->otmfsType = lpOTMW->otmfsType;
1259 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1260 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1261 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1262 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1263 lpOTM->otmAscent = lpOTMW->otmAscent;
1264 lpOTM->otmDescent = lpOTMW->otmDescent;
1265 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1266 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1267 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1268 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1269 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1270 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1271 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1272 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1273 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1274 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1275 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1276 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1277 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1278 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1279 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1280 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1283 ptr = (char*)(lpOTM + 1);
1284 left = needed - sizeof(*lpOTM);
1286 if(lpOTMW->otmpFamilyName) {
1287 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1288 len = WideCharToMultiByte(CP_ACP, 0,
1289 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1290 ptr, left, NULL, NULL);
1291 left -= len;
1292 ptr += len;
1293 } else
1294 lpOTM->otmpFamilyName = 0;
1296 if(lpOTMW->otmpFaceName) {
1297 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1298 len = WideCharToMultiByte(CP_ACP, 0,
1299 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1300 ptr, left, NULL, NULL);
1301 left -= len;
1302 ptr += len;
1303 } else
1304 lpOTM->otmpFaceName = 0;
1306 if(lpOTMW->otmpStyleName) {
1307 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1308 len = WideCharToMultiByte(CP_ACP, 0,
1309 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1310 ptr, left, NULL, NULL);
1311 left -= len;
1312 ptr += len;
1313 } else
1314 lpOTM->otmpStyleName = 0;
1316 if(lpOTMW->otmpFullName) {
1317 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1318 len = WideCharToMultiByte(CP_ACP, 0,
1319 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1320 ptr, left, NULL, NULL);
1321 left -= len;
1322 } else
1323 lpOTM->otmpFullName = 0;
1325 assert(left == 0);
1327 ret = needed;
1329 end:
1330 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1331 HeapFree(GetProcessHeap(), 0, lpOTMW);
1333 return ret;
1337 /***********************************************************************
1338 * GetOutlineTextMetricsW [GDI32.@]
1340 UINT WINAPI GetOutlineTextMetricsW(
1341 HDC hdc, /* [in] Handle of device context */
1342 UINT cbData, /* [in] Size of metric data array */
1343 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1345 DC *dc = DC_GetDCPtr( hdc );
1346 UINT ret;
1348 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1349 if(!dc) return 0;
1351 if(dc->gdiFont) {
1352 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1353 if(ret && ret <= cbData) {
1354 #define WDPTOLP(x) ((x<0)? \
1355 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1356 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1357 #define HDPTOLP(y) ((y<0)? \
1358 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1359 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1361 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1362 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1363 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1364 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1365 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1366 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1367 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1368 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1369 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1370 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1371 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1372 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1373 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1374 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1375 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1376 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1377 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1378 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1379 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1380 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1381 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1382 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1383 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1384 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1385 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1386 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1387 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1388 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1389 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1390 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1391 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1392 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1393 #undef WDPTOLP
1394 #undef HDPTOLP
1398 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1399 but really this should just be a return 0. */
1401 ret = sizeof(*lpOTM);
1402 if (lpOTM) {
1403 if(cbData < ret)
1404 ret = 0;
1405 else {
1406 memset(lpOTM, 0, ret);
1407 lpOTM->otmSize = sizeof(*lpOTM);
1408 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1410 Further fill of the structure not implemented,
1411 Needs real values for the structure members
1416 GDI_ReleaseObj(hdc);
1417 return ret;
1421 /***********************************************************************
1422 * GetCharWidthW (GDI32.@)
1423 * GetCharWidth32W (GDI32.@)
1425 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1426 LPINT buffer )
1428 UINT i, extra;
1429 BOOL ret = FALSE;
1430 DC * dc = DC_GetDCPtr( hdc );
1431 if (!dc) return FALSE;
1433 if (dc->gdiFont)
1434 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1435 else if (dc->funcs->pGetCharWidth)
1436 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1438 if (ret)
1440 /* convert device units to logical */
1442 extra = dc->vportExtX >> 1;
1443 for( i = firstChar; i <= lastChar; i++, buffer++ )
1444 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1445 ret = TRUE;
1447 GDI_ReleaseObj( hdc );
1448 return ret;
1452 /***********************************************************************
1453 * GetCharWidthA (GDI32.@)
1454 * GetCharWidth32A (GDI32.@)
1456 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1457 LPINT buffer )
1459 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1460 LPSTR str;
1461 LPWSTR wstr;
1462 BOOL ret = TRUE;
1464 if(count <= 0) return FALSE;
1466 str = HeapAlloc(GetProcessHeap(), 0, count);
1467 for(i = 0; i < count; i++)
1468 str[i] = (BYTE)(firstChar + i);
1470 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1472 for(i = 0; i < wlen; i++)
1474 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1476 ret = FALSE;
1477 break;
1479 buffer++;
1482 HeapFree(GetProcessHeap(), 0, str);
1483 HeapFree(GetProcessHeap(), 0, wstr);
1485 return ret;
1489 /* FIXME: all following APIs ******************************************/
1492 /***********************************************************************
1493 * SetMapperFlags (GDI32.@)
1495 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1497 DC *dc = DC_GetDCPtr( hDC );
1498 DWORD ret = 0;
1499 if(!dc) return 0;
1500 if(dc->funcs->pSetMapperFlags)
1501 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1502 else
1503 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1504 GDI_ReleaseObj( hDC );
1505 return ret;
1508 /***********************************************************************
1509 * GetAspectRatioFilterEx (GDI.486)
1511 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1513 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1514 return FALSE;
1517 /***********************************************************************
1518 * GetAspectRatioFilterEx (GDI32.@)
1520 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1522 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1523 return FALSE;
1527 /***********************************************************************
1528 * GetCharABCWidthsA (GDI32.@)
1530 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1531 LPABC abc )
1533 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1534 LPSTR str;
1535 LPWSTR wstr;
1536 BOOL ret = TRUE;
1538 if(count <= 0) return FALSE;
1540 str = HeapAlloc(GetProcessHeap(), 0, count);
1541 for(i = 0; i < count; i++)
1542 str[i] = (BYTE)(firstChar + i);
1544 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1546 for(i = 0; i < wlen; i++)
1548 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1550 ret = FALSE;
1551 break;
1553 abc++;
1556 HeapFree(GetProcessHeap(), 0, str);
1557 HeapFree(GetProcessHeap(), 0, wstr);
1559 return ret;
1563 /******************************************************************************
1564 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1566 * PARAMS
1567 * hdc [I] Handle of device context
1568 * firstChar [I] First character in range to query
1569 * lastChar [I] Last character in range to query
1570 * abc [O] Address of character-width structure
1572 * NOTES
1573 * Only works with TrueType fonts
1575 * RETURNS
1576 * Success: TRUE
1577 * Failure: FALSE
1579 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1580 LPABC abc )
1582 DC *dc = DC_GetDCPtr(hdc);
1583 int i;
1584 GLYPHMETRICS gm;
1585 BOOL ret = FALSE;
1587 if(dc->gdiFont) {
1588 for (i=firstChar;i<=lastChar;i++) {
1589 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1590 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1591 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1592 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1594 ret = TRUE;
1596 GDI_ReleaseObj(hdc);
1597 return ret;
1601 /***********************************************************************
1602 * GetGlyphOutline (GDI.309)
1604 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1605 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1606 LPVOID lpBuffer, const MAT2 *lpmat2 )
1608 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1609 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1610 return (DWORD)-1; /* failure */
1614 /***********************************************************************
1615 * GetGlyphOutlineA (GDI32.@)
1617 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1618 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1619 LPVOID lpBuffer, const MAT2 *lpmat2 )
1621 LPWSTR p = NULL;
1622 DWORD ret;
1623 UINT c;
1625 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1626 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1627 c = p[0];
1628 } else
1629 c = uChar;
1630 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1631 lpmat2);
1632 if(p)
1633 HeapFree(GetProcessHeap(), 0, p);
1634 return ret;
1637 /***********************************************************************
1638 * GetGlyphOutlineW (GDI32.@)
1640 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1641 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1642 LPVOID lpBuffer, const MAT2 *lpmat2 )
1644 DC *dc = DC_GetDCPtr(hdc);
1645 DWORD ret;
1647 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1648 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1650 if(!dc) return GDI_ERROR;
1652 if(dc->gdiFont)
1653 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1654 cbBuffer, lpBuffer, lpmat2);
1655 else
1656 ret = GDI_ERROR;
1658 GDI_ReleaseObj(hdc);
1659 return ret;
1663 /***********************************************************************
1664 * CreateScalableFontResourceA (GDI32.@)
1666 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1667 LPCSTR lpszResourceFile,
1668 LPCSTR lpszFontFile,
1669 LPCSTR lpszCurrentPath )
1671 HANDLE f;
1673 /* fHidden=1 - only visible for the calling app, read-only, not
1674 * enumbered with EnumFonts/EnumFontFamilies
1675 * lpszCurrentPath can be NULL
1677 FIXME("(%ld,%s,%s,%s): stub\n",
1678 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1679 debugstr_a(lpszCurrentPath) );
1681 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1682 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1683 CloseHandle(f);
1684 SetLastError(ERROR_FILE_EXISTS);
1685 return FALSE;
1687 return FALSE; /* create failed */
1690 /***********************************************************************
1691 * CreateScalableFontResourceW (GDI32.@)
1693 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1694 LPCWSTR lpszResourceFile,
1695 LPCWSTR lpszFontFile,
1696 LPCWSTR lpszCurrentPath )
1698 FIXME("(%ld,%p,%p,%p): stub\n",
1699 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1700 return FALSE; /* create failed */
1704 /*************************************************************************
1705 * GetRasterizerCaps (GDI32.@)
1707 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1709 lprs->nSize = sizeof(RASTERIZER_STATUS);
1710 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1711 lprs->nLanguageID = 0;
1712 return TRUE;
1716 /*************************************************************************
1717 * GetKerningPairsA (GDI32.@)
1719 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1720 LPKERNINGPAIR lpKerningPairs )
1722 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1726 /*************************************************************************
1727 * GetKerningPairsW (GDI32.@)
1729 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1730 LPKERNINGPAIR lpKerningPairs )
1732 int i;
1733 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1734 for (i = 0; i < cPairs; i++)
1735 lpKerningPairs[i].iKernAmount = 0;
1736 return 0;
1739 /*************************************************************************
1740 * TranslateCharsetInfo [GDI32.@]
1742 * Fills a CHARSETINFO structure for a character set, code page, or
1743 * font. This allows making the correspondance between different labelings
1744 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1745 * of the same encoding.
1747 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1748 * only one codepage should be set in *lpSrc.
1750 * RETURNS
1751 * TRUE on success, FALSE on failure.
1754 BOOL WINAPI TranslateCharsetInfo(
1755 LPDWORD lpSrc, /* [in]
1756 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1757 if flags == TCI_SRCCHARSET: a character set value
1758 if flags == TCI_SRCCODEPAGE: a code page value
1760 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1761 DWORD flags /* [in] determines interpretation of lpSrc */
1763 int index = 0;
1764 switch (flags) {
1765 case TCI_SRCFONTSIG:
1766 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1767 break;
1768 case TCI_SRCCODEPAGE:
1769 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1770 break;
1771 case TCI_SRCCHARSET:
1772 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1773 break;
1774 default:
1775 return FALSE;
1777 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1778 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1779 return TRUE;
1782 /*************************************************************************
1783 * GetFontLanguageInfo (GDI32.@)
1785 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1787 FONTSIGNATURE fontsig;
1788 static const DWORD GCP_DBCS_MASK=0x003F0000,
1789 GCP_DIACRITIC_MASK=0x00000000,
1790 FLI_GLYPHS_MASK=0x00000000,
1791 GCP_GLYPHSHAPE_MASK=0x00000040,
1792 GCP_KASHIDA_MASK=0x00000000,
1793 GCP_LIGATE_MASK=0x00000000,
1794 GCP_USEKERNING_MASK=0x00000000,
1795 GCP_REORDER_MASK=0x00000060;
1797 DWORD result=0;
1799 GetTextCharsetInfo( hdc, &fontsig, 0 );
1800 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1802 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1803 result|=GCP_DBCS;
1805 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1806 result|=GCP_DIACRITIC;
1808 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1809 result|=FLI_GLYPHS;
1811 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1812 result|=GCP_GLYPHSHAPE;
1814 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1815 result|=GCP_KASHIDA;
1817 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1818 result|=GCP_LIGATE;
1820 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1821 result|=GCP_USEKERNING;
1823 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1824 result|=GCP_REORDER;
1826 return result;
1830 /*************************************************************************
1831 * GetFontData [GDI32.@] Retrieve data for TrueType font
1833 * RETURNS
1835 * success: Number of bytes returned
1836 * failure: GDI_ERROR
1838 * NOTES
1840 * Calls SetLastError()
1843 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1844 LPVOID buffer, DWORD length)
1846 DC *dc = DC_GetDCPtr(hdc);
1847 DWORD ret = GDI_ERROR;
1849 if(!dc) return GDI_ERROR;
1851 if(dc->gdiFont)
1852 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1854 GDI_ReleaseObj(hdc);
1855 return ret;
1858 /*************************************************************************
1859 * GetGlyphIndicesA [GDI32.@]
1861 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1862 LPWORD pgi, DWORD flags)
1864 DWORD ret;
1865 WCHAR *lpstrW;
1866 INT countW;
1868 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1869 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1871 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1872 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1873 HeapFree(GetProcessHeap(), 0, lpstrW);
1875 return ret;
1878 /*************************************************************************
1879 * GetGlyphIndicesW [GDI32.@]
1881 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1882 LPWORD pgi, DWORD flags)
1884 DC *dc = DC_GetDCPtr(hdc);
1885 DWORD ret = GDI_ERROR;
1887 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1888 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1890 if(!dc) return GDI_ERROR;
1892 if(dc->gdiFont)
1893 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1895 GDI_ReleaseObj(hdc);
1896 return ret;
1899 /*************************************************************************
1900 * GetCharacterPlacementA [GDI32.@]
1902 * NOTES:
1903 * the web browser control of ie4 calls this with dwFlags=0
1905 DWORD WINAPI
1906 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1907 INT nMaxExtent, GCP_RESULTSA *lpResults,
1908 DWORD dwFlags)
1910 WCHAR *lpStringW;
1911 INT uCountW, i;
1912 GCP_RESULTSW resultsW;
1913 DWORD ret;
1914 UINT font_cp;
1916 TRACE("%s, %d, %d, 0x%08lx\n",
1917 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1919 /* both structs are equal in size */
1920 memcpy(&resultsW, lpResults, sizeof(resultsW));
1922 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1923 if(lpResults->lpOutString)
1924 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1926 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1928 if(lpResults->lpOutString) {
1929 if(font_cp != CP_SYMBOL)
1930 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1931 lpResults->lpOutString, uCount, NULL, NULL );
1932 else
1933 for(i = 0; i < uCount; i++)
1934 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1937 HeapFree(GetProcessHeap(), 0, lpStringW);
1938 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1940 return ret;
1943 /*************************************************************************
1944 * GetCharacterPlacementW [GDI32.@]
1946 * Retrieve information about a string. This includes the width, reordering,
1947 * Glyphing and so on.
1949 * RETURNS
1951 * The width and height of the string if successful, 0 if failed.
1953 * BUGS
1955 * All flags except GCP_REORDER are not yet implemented.
1956 * Reordering is not 100% complient to the Windows BiDi method.
1957 * Caret positioning is not yet implemented.
1958 * Classes are not yet implemented.
1961 DWORD WINAPI
1962 GetCharacterPlacementW(
1963 HDC hdc, /* [in] Device context for which the rendering is to be done */
1964 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1965 INT uCount, /* [in] Number of WORDS in string. */
1966 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1967 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1968 DWORD dwFlags /* [in] Flags specifying how to process the string */
1971 DWORD ret=0;
1972 SIZE size;
1973 UINT i, nSet;
1975 TRACE("%s, %d, %d, 0x%08lx\n",
1976 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1978 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1979 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1980 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1981 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1982 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1984 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1985 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1986 if(lpResults->lpClass) FIXME("classes not implemented\n");
1988 nSet = (UINT)uCount;
1989 if(nSet > lpResults->nGlyphs)
1990 nSet = lpResults->nGlyphs;
1992 /* return number of initialized fields */
1993 lpResults->nGlyphs = nSet;
1995 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
1997 /* Treat the case where no special handling was requested in a fastpath way */
1998 /* copy will do if the GCP_REORDER flag is not set */
1999 if(lpResults->lpOutString)
2000 strncpyW( lpResults->lpOutString, lpString, nSet );
2002 if(lpResults->lpOrder)
2004 for(i = 0; i < nSet; i++)
2005 lpResults->lpOrder[i] = i;
2007 } else
2009 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2010 nSet, lpResults->lpOrder );
2013 /* FIXME: Will use the placement chars */
2014 if (lpResults->lpDx)
2016 int c;
2017 for (i = 0; i < nSet; i++)
2019 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2020 lpResults->lpDx[i]= c;
2024 if(lpResults->lpGlyphs)
2025 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2027 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2028 ret = MAKELONG(size.cx, size.cy);
2030 return ret;
2033 /*************************************************************************
2034 * GetCharABCWidthsFloatA [GDI32.@]
2036 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2037 LPABCFLOAT lpABCF)
2039 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2040 return 0;
2043 /*************************************************************************
2044 * GetCharABCWidthsFloatW [GDI32.@]
2046 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2047 UINT iLastChar, LPABCFLOAT lpABCF)
2049 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2050 return 0;
2053 /*************************************************************************
2054 * GetCharWidthFloatA [GDI32.@]
2056 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2057 UINT iLastChar, PFLOAT pxBuffer)
2059 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2060 return 0;
2063 /*************************************************************************
2064 * GetCharWidthFloatW [GDI32.@]
2066 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2067 UINT iLastChar, PFLOAT pxBuffer)
2069 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2070 return 0;
2074 /***********************************************************************
2076 * Font Resource API *
2078 ***********************************************************************/
2080 /***********************************************************************
2081 * AddFontResourceA (GDI32.@)
2083 INT WINAPI AddFontResourceA( LPCSTR str )
2085 return AddFontResourceExA( str, 0, NULL);
2088 /***********************************************************************
2089 * AddFontResourceW (GDI32.@)
2091 INT WINAPI AddFontResourceW( LPCWSTR str )
2093 return AddFontResourceExW(str, 0, NULL);
2097 /***********************************************************************
2098 * AddFontResourceExA (GDI32.@)
2100 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2102 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2103 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2104 INT ret;
2106 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2107 ret = AddFontResourceExW(strW, fl, pdv);
2108 HeapFree(GetProcessHeap(), 0, strW);
2109 return ret;
2112 /***********************************************************************
2113 * AddFontResourceExW (GDI32.@)
2115 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2117 return WineEngAddFontResourceEx(str, fl, pdv);
2120 /***********************************************************************
2121 * RemoveFontResourceA (GDI32.@)
2123 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2125 return RemoveFontResourceExA(str, 0, 0);
2128 /***********************************************************************
2129 * RemoveFontResourceW (GDI32.@)
2131 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2133 return RemoveFontResourceExW(str, 0, 0);
2136 /***********************************************************************
2137 * RemoveFontResourceExA (GDI32.@)
2139 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2141 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2142 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2143 INT ret;
2145 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2146 ret = RemoveFontResourceExW(strW, fl, pdv);
2147 HeapFree(GetProcessHeap(), 0, strW);
2148 return ret;
2151 /***********************************************************************
2152 * RemoveFontResourceExW (GDI32.@)
2154 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2156 return WineEngRemoveFontResourceEx(str, fl, pdv);
2159 /***********************************************************************
2160 * GetTextCharset (GDI32.@)
2162 UINT WINAPI GetTextCharset(HDC hdc)
2164 /* MSDN docs say this is equivalent */
2165 return GetTextCharsetInfo(hdc, NULL, 0);
2168 /***********************************************************************
2169 * GetTextCharsetInfo (GDI32.@)
2171 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2173 UINT ret = DEFAULT_CHARSET;
2174 DC *dc = DC_GetDCPtr(hdc);
2176 if (!dc) goto done;
2178 if (dc->gdiFont)
2179 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2181 GDI_ReleaseObj(hdc);
2183 done:
2184 if (ret == DEFAULT_CHARSET && fs)
2185 memset(fs, 0, sizeof(FONTSIGNATURE));
2186 return ret;