Convert initData as well.
[wine/multimedia.git] / objects / font.c
blobbdc613a729fe2a6e05b5349a210b5056b3a5717a
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 > 255 ? 255 : ptmW->tmFirstChar;
239 ptmA->tmLastChar = ptmW->tmLastChar > 255 ? 255 : ptmW->tmLastChar;
240 ptmA->tmDefaultChar = ptmW->tmDefaultChar > 255 ? 255 : ptmW->tmDefaultChar;
241 ptmA->tmBreakChar = ptmW->tmBreakChar > 255 ? 255 : 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 > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
264 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
265 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
266 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : 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;
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 */
1441 for( i = firstChar; i <= lastChar; i++, buffer++ )
1442 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1443 ret = TRUE;
1445 GDI_ReleaseObj( hdc );
1446 return ret;
1450 /***********************************************************************
1451 * GetCharWidthA (GDI32.@)
1452 * GetCharWidth32A (GDI32.@)
1454 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1455 LPINT buffer )
1457 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1458 LPSTR str;
1459 LPWSTR wstr;
1460 BOOL ret = TRUE;
1462 if(count <= 0) return FALSE;
1464 str = HeapAlloc(GetProcessHeap(), 0, count);
1465 for(i = 0; i < count; i++)
1466 str[i] = (BYTE)(firstChar + i);
1468 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1470 for(i = 0; i < wlen; i++)
1472 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1474 ret = FALSE;
1475 break;
1477 buffer++;
1480 HeapFree(GetProcessHeap(), 0, str);
1481 HeapFree(GetProcessHeap(), 0, wstr);
1483 return ret;
1487 /* FIXME: all following APIs ******************************************/
1490 /***********************************************************************
1491 * SetMapperFlags (GDI32.@)
1493 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1495 DC *dc = DC_GetDCPtr( hDC );
1496 DWORD ret = 0;
1497 if(!dc) return 0;
1498 if(dc->funcs->pSetMapperFlags)
1499 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1500 else
1501 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1502 GDI_ReleaseObj( hDC );
1503 return ret;
1506 /***********************************************************************
1507 * GetAspectRatioFilterEx (GDI.486)
1509 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1511 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1512 return FALSE;
1515 /***********************************************************************
1516 * GetAspectRatioFilterEx (GDI32.@)
1518 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1520 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1521 return FALSE;
1525 /***********************************************************************
1526 * GetCharABCWidthsA (GDI32.@)
1528 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1529 LPABC abc )
1531 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1532 LPSTR str;
1533 LPWSTR wstr;
1534 BOOL ret = TRUE;
1536 if(count <= 0) return FALSE;
1538 str = HeapAlloc(GetProcessHeap(), 0, count);
1539 for(i = 0; i < count; i++)
1540 str[i] = (BYTE)(firstChar + i);
1542 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1544 for(i = 0; i < wlen; i++)
1546 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1548 ret = FALSE;
1549 break;
1551 abc++;
1554 HeapFree(GetProcessHeap(), 0, str);
1555 HeapFree(GetProcessHeap(), 0, wstr);
1557 return ret;
1561 /******************************************************************************
1562 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1564 * PARAMS
1565 * hdc [I] Handle of device context
1566 * firstChar [I] First character in range to query
1567 * lastChar [I] Last character in range to query
1568 * abc [O] Address of character-width structure
1570 * NOTES
1571 * Only works with TrueType fonts
1573 * RETURNS
1574 * Success: TRUE
1575 * Failure: FALSE
1577 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1578 LPABC abc )
1580 DC *dc = DC_GetDCPtr(hdc);
1581 int i;
1582 GLYPHMETRICS gm;
1583 BOOL ret = FALSE;
1585 if(dc->gdiFont) {
1586 for (i=firstChar;i<=lastChar;i++) {
1587 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1588 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1589 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1590 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1592 ret = TRUE;
1594 GDI_ReleaseObj(hdc);
1595 return ret;
1599 /***********************************************************************
1600 * GetGlyphOutline (GDI.309)
1602 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1603 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1604 LPVOID lpBuffer, const MAT2 *lpmat2 )
1606 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1607 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1608 return (DWORD)-1; /* failure */
1612 /***********************************************************************
1613 * GetGlyphOutlineA (GDI32.@)
1615 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1616 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1617 LPVOID lpBuffer, const MAT2 *lpmat2 )
1619 LPWSTR p = NULL;
1620 DWORD ret;
1621 UINT c;
1623 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1624 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1625 c = p[0];
1626 } else
1627 c = uChar;
1628 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1629 lpmat2);
1630 if(p)
1631 HeapFree(GetProcessHeap(), 0, p);
1632 return ret;
1635 /***********************************************************************
1636 * GetGlyphOutlineW (GDI32.@)
1638 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1639 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1640 LPVOID lpBuffer, const MAT2 *lpmat2 )
1642 DC *dc = DC_GetDCPtr(hdc);
1643 DWORD ret;
1645 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1646 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1648 if(!dc) return GDI_ERROR;
1650 if(dc->gdiFont)
1651 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1652 cbBuffer, lpBuffer, lpmat2);
1653 else
1654 ret = GDI_ERROR;
1656 GDI_ReleaseObj(hdc);
1657 return ret;
1661 /***********************************************************************
1662 * CreateScalableFontResourceA (GDI32.@)
1664 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1665 LPCSTR lpszResourceFile,
1666 LPCSTR lpszFontFile,
1667 LPCSTR lpszCurrentPath )
1669 HANDLE f;
1671 /* fHidden=1 - only visible for the calling app, read-only, not
1672 * enumbered with EnumFonts/EnumFontFamilies
1673 * lpszCurrentPath can be NULL
1675 FIXME("(%ld,%s,%s,%s): stub\n",
1676 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1677 debugstr_a(lpszCurrentPath) );
1679 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1680 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1681 CloseHandle(f);
1682 SetLastError(ERROR_FILE_EXISTS);
1683 return FALSE;
1685 return FALSE; /* create failed */
1688 /***********************************************************************
1689 * CreateScalableFontResourceW (GDI32.@)
1691 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1692 LPCWSTR lpszResourceFile,
1693 LPCWSTR lpszFontFile,
1694 LPCWSTR lpszCurrentPath )
1696 FIXME("(%ld,%p,%p,%p): stub\n",
1697 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1698 return FALSE; /* create failed */
1702 /*************************************************************************
1703 * GetRasterizerCaps (GDI32.@)
1705 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1707 lprs->nSize = sizeof(RASTERIZER_STATUS);
1708 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1709 lprs->nLanguageID = 0;
1710 return TRUE;
1714 /*************************************************************************
1715 * GetKerningPairsA (GDI32.@)
1717 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1718 LPKERNINGPAIR lpKerningPairs )
1720 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
1724 /*************************************************************************
1725 * GetKerningPairsW (GDI32.@)
1727 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1728 LPKERNINGPAIR lpKerningPairs )
1730 int i;
1731 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1732 for (i = 0; i < cPairs; i++)
1733 lpKerningPairs[i].iKernAmount = 0;
1734 return 0;
1737 /*************************************************************************
1738 * TranslateCharsetInfo [GDI32.@]
1740 * Fills a CHARSETINFO structure for a character set, code page, or
1741 * font. This allows making the correspondance between different labelings
1742 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1743 * of the same encoding.
1745 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1746 * only one codepage should be set in *lpSrc.
1748 * RETURNS
1749 * TRUE on success, FALSE on failure.
1752 BOOL WINAPI TranslateCharsetInfo(
1753 LPDWORD lpSrc, /* [in]
1754 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1755 if flags == TCI_SRCCHARSET: a character set value
1756 if flags == TCI_SRCCODEPAGE: a code page value
1758 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1759 DWORD flags /* [in] determines interpretation of lpSrc */
1761 int index = 0;
1762 switch (flags) {
1763 case TCI_SRCFONTSIG:
1764 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1765 break;
1766 case TCI_SRCCODEPAGE:
1767 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1768 break;
1769 case TCI_SRCCHARSET:
1770 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1771 break;
1772 default:
1773 return FALSE;
1775 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1776 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1777 return TRUE;
1780 /*************************************************************************
1781 * GetFontLanguageInfo (GDI32.@)
1783 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1785 FONTSIGNATURE fontsig;
1786 static const DWORD GCP_DBCS_MASK=0x003F0000,
1787 GCP_DIACRITIC_MASK=0x00000000,
1788 FLI_GLYPHS_MASK=0x00000000,
1789 GCP_GLYPHSHAPE_MASK=0x00000040,
1790 GCP_KASHIDA_MASK=0x00000000,
1791 GCP_LIGATE_MASK=0x00000000,
1792 GCP_USEKERNING_MASK=0x00000000,
1793 GCP_REORDER_MASK=0x00000060;
1795 DWORD result=0;
1797 GetTextCharsetInfo( hdc, &fontsig, 0 );
1798 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1800 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1801 result|=GCP_DBCS;
1803 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1804 result|=GCP_DIACRITIC;
1806 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1807 result|=FLI_GLYPHS;
1809 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1810 result|=GCP_GLYPHSHAPE;
1812 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1813 result|=GCP_KASHIDA;
1815 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1816 result|=GCP_LIGATE;
1818 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1819 result|=GCP_USEKERNING;
1821 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1822 result|=GCP_REORDER;
1824 return result;
1828 /*************************************************************************
1829 * GetFontData [GDI32.@] Retrieve data for TrueType font
1831 * RETURNS
1833 * success: Number of bytes returned
1834 * failure: GDI_ERROR
1836 * NOTES
1838 * Calls SetLastError()
1841 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1842 LPVOID buffer, DWORD length)
1844 DC *dc = DC_GetDCPtr(hdc);
1845 DWORD ret = GDI_ERROR;
1847 if(!dc) return GDI_ERROR;
1849 if(dc->gdiFont)
1850 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1852 GDI_ReleaseObj(hdc);
1853 return ret;
1856 /*************************************************************************
1857 * GetGlyphIndicesA [GDI32.@]
1859 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1860 LPWORD pgi, DWORD flags)
1862 DWORD ret;
1863 WCHAR *lpstrW;
1864 INT countW;
1866 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1867 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1869 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1870 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1871 HeapFree(GetProcessHeap(), 0, lpstrW);
1873 return ret;
1876 /*************************************************************************
1877 * GetGlyphIndicesW [GDI32.@]
1879 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1880 LPWORD pgi, DWORD flags)
1882 DC *dc = DC_GetDCPtr(hdc);
1883 DWORD ret = GDI_ERROR;
1885 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1886 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1888 if(!dc) return GDI_ERROR;
1890 if(dc->gdiFont)
1891 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1893 GDI_ReleaseObj(hdc);
1894 return ret;
1897 /*************************************************************************
1898 * GetCharacterPlacementA [GDI32.@]
1900 * NOTES:
1901 * the web browser control of ie4 calls this with dwFlags=0
1903 DWORD WINAPI
1904 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1905 INT nMaxExtent, GCP_RESULTSA *lpResults,
1906 DWORD dwFlags)
1908 WCHAR *lpStringW;
1909 INT uCountW, i;
1910 GCP_RESULTSW resultsW;
1911 DWORD ret;
1912 UINT font_cp;
1914 TRACE("%s, %d, %d, 0x%08lx\n",
1915 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1917 /* both structs are equal in size */
1918 memcpy(&resultsW, lpResults, sizeof(resultsW));
1920 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1921 if(lpResults->lpOutString)
1922 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1924 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1926 if(lpResults->lpOutString) {
1927 if(font_cp != CP_SYMBOL)
1928 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1929 lpResults->lpOutString, uCount, NULL, NULL );
1930 else
1931 for(i = 0; i < uCount; i++)
1932 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1935 HeapFree(GetProcessHeap(), 0, lpStringW);
1936 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1938 return ret;
1941 /*************************************************************************
1942 * GetCharacterPlacementW [GDI32.@]
1944 * Retrieve information about a string. This includes the width, reordering,
1945 * Glyphing and so on.
1947 * RETURNS
1949 * The width and height of the string if successful, 0 if failed.
1951 * BUGS
1953 * All flags except GCP_REORDER are not yet implemented.
1954 * Reordering is not 100% complient to the Windows BiDi method.
1955 * Caret positioning is not yet implemented.
1956 * Classes are not yet implemented.
1959 DWORD WINAPI
1960 GetCharacterPlacementW(
1961 HDC hdc, /* [in] Device context for which the rendering is to be done */
1962 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1963 INT uCount, /* [in] Number of WORDS in string. */
1964 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1965 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1966 DWORD dwFlags /* [in] Flags specifying how to process the string */
1969 DWORD ret=0;
1970 SIZE size;
1971 UINT i, nSet;
1973 TRACE("%s, %d, %d, 0x%08lx\n",
1974 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1976 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1977 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1978 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1979 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1980 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1982 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1983 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1984 if(lpResults->lpClass) FIXME("classes not implemented\n");
1986 nSet = (UINT)uCount;
1987 if(nSet > lpResults->nGlyphs)
1988 nSet = lpResults->nGlyphs;
1990 /* return number of initialized fields */
1991 lpResults->nGlyphs = nSet;
1993 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
1995 /* Treat the case where no special handling was requested in a fastpath way */
1996 /* copy will do if the GCP_REORDER flag is not set */
1997 if(lpResults->lpOutString)
1998 strncpyW( lpResults->lpOutString, lpString, nSet );
2000 if(lpResults->lpOrder)
2002 for(i = 0; i < nSet; i++)
2003 lpResults->lpOrder[i] = i;
2005 } else
2007 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2008 nSet, lpResults->lpOrder );
2011 /* FIXME: Will use the placement chars */
2012 if (lpResults->lpDx)
2014 int c;
2015 for (i = 0; i < nSet; i++)
2017 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2018 lpResults->lpDx[i]= c;
2022 if(lpResults->lpGlyphs)
2023 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2025 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2026 ret = MAKELONG(size.cx, size.cy);
2028 return ret;
2031 /*************************************************************************
2032 * GetCharABCWidthsFloatA [GDI32.@]
2034 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2035 LPABCFLOAT lpABCF)
2037 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2038 return 0;
2041 /*************************************************************************
2042 * GetCharABCWidthsFloatW [GDI32.@]
2044 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2045 UINT iLastChar, LPABCFLOAT lpABCF)
2047 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2048 return 0;
2051 /*************************************************************************
2052 * GetCharWidthFloatA [GDI32.@]
2054 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2055 UINT iLastChar, PFLOAT pxBuffer)
2057 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2058 return 0;
2061 /*************************************************************************
2062 * GetCharWidthFloatW [GDI32.@]
2064 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2065 UINT iLastChar, PFLOAT pxBuffer)
2067 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2068 return 0;
2072 /***********************************************************************
2074 * Font Resource API *
2076 ***********************************************************************/
2078 /***********************************************************************
2079 * AddFontResourceA (GDI32.@)
2081 INT WINAPI AddFontResourceA( LPCSTR str )
2083 return AddFontResourceExA( str, 0, NULL);
2086 /***********************************************************************
2087 * AddFontResourceW (GDI32.@)
2089 INT WINAPI AddFontResourceW( LPCWSTR str )
2091 return AddFontResourceExW(str, 0, NULL);
2095 /***********************************************************************
2096 * AddFontResourceExA (GDI32.@)
2098 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2100 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2101 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2102 INT ret;
2104 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2105 ret = AddFontResourceExW(strW, fl, pdv);
2106 HeapFree(GetProcessHeap(), 0, strW);
2107 return ret;
2110 /***********************************************************************
2111 * AddFontResourceExW (GDI32.@)
2113 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2115 return WineEngAddFontResourceEx(str, fl, pdv);
2118 /***********************************************************************
2119 * RemoveFontResourceA (GDI32.@)
2121 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2123 return RemoveFontResourceExA(str, 0, 0);
2126 /***********************************************************************
2127 * RemoveFontResourceW (GDI32.@)
2129 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2131 return RemoveFontResourceExW(str, 0, 0);
2134 /***********************************************************************
2135 * RemoveFontResourceExA (GDI32.@)
2137 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2139 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2140 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2141 INT ret;
2143 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2144 ret = RemoveFontResourceExW(strW, fl, pdv);
2145 HeapFree(GetProcessHeap(), 0, strW);
2146 return ret;
2149 /***********************************************************************
2150 * RemoveFontResourceExW (GDI32.@)
2152 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2154 return WineEngRemoveFontResourceEx(str, fl, pdv);
2157 /***********************************************************************
2158 * GetTextCharset (GDI32.@)
2160 UINT WINAPI GetTextCharset(HDC hdc)
2162 /* MSDN docs say this is equivalent */
2163 return GetTextCharsetInfo(hdc, NULL, 0);
2166 /***********************************************************************
2167 * GetTextCharsetInfo (GDI32.@)
2169 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2171 UINT ret = DEFAULT_CHARSET;
2172 DC *dc = DC_GetDCPtr(hdc);
2174 if (!dc) goto done;
2176 if (dc->gdiFont)
2177 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2179 GDI_ReleaseObj(hdc);
2181 done:
2182 if (ret == DEFAULT_CHARSET && fs)
2183 memset(fs, 0, sizeof(FONTSIGNATURE));
2184 return ret;