Add IStream and IStorage interface entries.
[wine/testsucceed.git] / objects / font.c
blob04812b00d258e4d5795803f80eafa78bc6bbe453
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "config.h"
23 #include "wine/port.h"
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include "winerror.h"
29 #include "winnls.h"
30 #include "wine/unicode.h"
31 #include "font.h"
32 #include "wine/debug.h"
33 #include "gdi.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(font);
36 WINE_DECLARE_DEBUG_CHANNEL(gdi);
38 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
39 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
40 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
41 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
44 static const struct gdi_obj_funcs font_funcs =
46 FONT_SelectObject, /* pSelectObject */
47 FONT_GetObject16, /* pGetObject16 */
48 FONT_GetObjectA, /* pGetObjectA */
49 FONT_GetObjectW, /* pGetObjectW */
50 NULL, /* pUnrealizeObject */
51 FONT_DeleteObject /* pDeleteObject */
54 #define ENUM_UNICODE 0x00000001
55 #define ENUM_CALLED 0x00000002
57 typedef struct
59 GDIOBJHDR header;
60 LOGFONTW logfont;
61 } FONTOBJ;
63 typedef struct
65 LPLOGFONT16 lpLogFontParam;
66 FONTENUMPROC16 lpEnumFunc;
67 LPARAM lpData;
69 LPNEWTEXTMETRICEX16 lpTextMetric;
70 LPENUMLOGFONTEX16 lpLogFont;
71 SEGPTR segTextMetric;
72 SEGPTR segLogFont;
73 HDC hdc;
74 DC *dc;
75 PHYSDEV physDev;
76 } fontEnum16;
78 typedef struct
80 LPLOGFONTW lpLogFontParam;
81 FONTENUMPROCW lpEnumFunc;
82 LPARAM lpData;
83 DWORD dwFlags;
84 HDC hdc;
85 DC *dc;
86 PHYSDEV physDev;
87 } fontEnum32;
90 * For TranslateCharsetInfo
92 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
93 #define MAXTCIINDEX 32
94 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
95 /* ANSI */
96 { ANSI_CHARSET, 1252, FS(0)},
97 { EASTEUROPE_CHARSET, 1250, FS(1)},
98 { RUSSIAN_CHARSET, 1251, FS(2)},
99 { GREEK_CHARSET, 1253, FS(3)},
100 { TURKISH_CHARSET, 1254, FS(4)},
101 { HEBREW_CHARSET, 1255, FS(5)},
102 { ARABIC_CHARSET, 1256, FS(6)},
103 { BALTIC_CHARSET, 1257, FS(7)},
104 { VIETNAMESE_CHARSET, 1258, FS(8)},
105 /* reserved by ANSI */
106 { DEFAULT_CHARSET, 0, FS(0)},
107 { DEFAULT_CHARSET, 0, FS(0)},
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 /* ANSI and OEM */
114 { THAI_CHARSET, 874, FS(16)},
115 { SHIFTJIS_CHARSET, 932, FS(17)},
116 { GB2312_CHARSET, 936, FS(18)},
117 { HANGEUL_CHARSET, 949, FS(19)},
118 { CHINESEBIG5_CHARSET, 950, FS(20)},
119 { JOHAB_CHARSET, 1361, FS(21)},
120 /* reserved for alternate ANSI and OEM */
121 { DEFAULT_CHARSET, 0, FS(0)},
122 { DEFAULT_CHARSET, 0, FS(0)},
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 /* reserved for system */
130 { DEFAULT_CHARSET, 0, FS(0)},
131 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
134 /* ### start build ### */
135 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROC16,LONG,LONG,WORD,LONG);
136 /* ### stop build ### */
138 /***********************************************************************
139 * LOGFONT conversion functions.
141 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
143 font16->lfHeight = font32->lfHeight;
144 font16->lfWidth = font32->lfWidth;
145 font16->lfEscapement = font32->lfEscapement;
146 font16->lfOrientation = font32->lfOrientation;
147 font16->lfWeight = font32->lfWeight;
148 font16->lfItalic = font32->lfItalic;
149 font16->lfUnderline = font32->lfUnderline;
150 font16->lfStrikeOut = font32->lfStrikeOut;
151 font16->lfCharSet = font32->lfCharSet;
152 font16->lfOutPrecision = font32->lfOutPrecision;
153 font16->lfClipPrecision = font32->lfClipPrecision;
154 font16->lfQuality = font32->lfQuality;
155 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
156 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
157 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
158 font16->lfFaceName[LF_FACESIZE-1] = 0;
161 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
163 font32->lfHeight = font16->lfHeight;
164 font32->lfWidth = font16->lfWidth;
165 font32->lfEscapement = font16->lfEscapement;
166 font32->lfOrientation = font16->lfOrientation;
167 font32->lfWeight = font16->lfWeight;
168 font32->lfItalic = font16->lfItalic;
169 font32->lfUnderline = font16->lfUnderline;
170 font32->lfStrikeOut = font16->lfStrikeOut;
171 font32->lfCharSet = font16->lfCharSet;
172 font32->lfOutPrecision = font16->lfOutPrecision;
173 font32->lfClipPrecision = font16->lfClipPrecision;
174 font32->lfQuality = font16->lfQuality;
175 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
176 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
177 font32->lfFaceName[LF_FACESIZE-1] = 0;
180 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
182 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
183 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
184 LF_FACESIZE);
187 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
189 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
190 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
191 LF_FACESIZE, NULL, NULL);
194 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
196 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
198 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
199 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
200 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
201 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
202 font16->elfStyle, LF_FACESIZE, NULL, NULL );
203 font16->elfStyle[LF_FACESIZE-1] = '\0';
204 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
205 font16->elfScript, LF_FACESIZE, NULL, NULL );
206 font16->elfScript[LF_FACESIZE-1] = '\0';
209 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
211 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
213 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
214 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
215 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
216 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
217 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
218 fontA->elfStyle[LF_FACESIZE-1] = '\0';
219 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
220 fontA->elfScript, LF_FACESIZE, NULL, NULL );
221 fontA->elfScript[LF_FACESIZE-1] = '\0';
224 /***********************************************************************
225 * TEXTMETRIC conversion functions.
227 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
229 ptmA->tmHeight = ptmW->tmHeight;
230 ptmA->tmAscent = ptmW->tmAscent;
231 ptmA->tmDescent = ptmW->tmDescent;
232 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
233 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
234 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
235 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
236 ptmA->tmWeight = ptmW->tmWeight;
237 ptmA->tmOverhang = ptmW->tmOverhang;
238 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
239 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
240 ptmA->tmFirstChar = ptmW->tmFirstChar;
241 ptmA->tmLastChar = ptmW->tmLastChar;
242 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
243 ptmA->tmBreakChar = ptmW->tmBreakChar;
244 ptmA->tmItalic = ptmW->tmItalic;
245 ptmA->tmUnderlined = ptmW->tmUnderlined;
246 ptmA->tmStruckOut = ptmW->tmStruckOut;
247 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
248 ptmA->tmCharSet = ptmW->tmCharSet;
252 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
254 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
255 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
256 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
257 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
258 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
259 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
260 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
261 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
262 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
263 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
264 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
265 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
266 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
267 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
268 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
269 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
270 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
271 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
272 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
273 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
274 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
275 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
276 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
277 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
278 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
281 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
283 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
284 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
285 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
286 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
287 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
288 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
291 /***********************************************************************
292 * CreateFontIndirectA (GDI32.@)
294 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
296 LOGFONTW lfW;
298 if (plfA) {
299 FONT_LogFontAToW( plfA, &lfW );
300 return CreateFontIndirectW( &lfW );
301 } else
302 return CreateFontIndirectW( NULL );
306 /***********************************************************************
307 * CreateFontIndirectW (GDI32.@)
309 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
311 HFONT hFont = 0;
313 if (plf)
315 FONTOBJ* fontPtr;
316 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
318 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
320 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
321 plf->lfHeight, plf->lfWidth,
322 plf->lfEscapement, plf->lfOrientation,
323 plf->lfPitchAndFamily,
324 debugstr_w(plf->lfFaceName),
325 plf->lfWeight > 400 ? "Bold" : "",
326 plf->lfItalic ? "Italic" : "", hFont);
328 if (plf->lfEscapement != plf->lfOrientation) {
329 /* this should really depend on whether GM_ADVANCED is set */
330 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
331 WARN("orientation angle %f set to "
332 "escapement angle %f for new font %04x\n",
333 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
335 GDI_ReleaseObj( hFont );
338 else WARN("(NULL) => NULL\n");
340 return hFont;
343 /*************************************************************************
344 * CreateFontA (GDI32.@)
346 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
347 INT orient, INT weight, DWORD italic,
348 DWORD underline, DWORD strikeout, DWORD charset,
349 DWORD outpres, DWORD clippres, DWORD quality,
350 DWORD pitch, LPCSTR name )
352 LOGFONTA logfont;
354 logfont.lfHeight = height;
355 logfont.lfWidth = width;
356 logfont.lfEscapement = esc;
357 logfont.lfOrientation = orient;
358 logfont.lfWeight = weight;
359 logfont.lfItalic = italic;
360 logfont.lfUnderline = underline;
361 logfont.lfStrikeOut = strikeout;
362 logfont.lfCharSet = charset;
363 logfont.lfOutPrecision = outpres;
364 logfont.lfClipPrecision = clippres;
365 logfont.lfQuality = quality;
366 logfont.lfPitchAndFamily = pitch;
368 if (name)
369 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
370 else
371 logfont.lfFaceName[0] = '\0';
373 return CreateFontIndirectA( &logfont );
376 /*************************************************************************
377 * CreateFontW (GDI32.@)
379 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
380 INT orient, INT weight, DWORD italic,
381 DWORD underline, DWORD strikeout, DWORD charset,
382 DWORD outpres, DWORD clippres, DWORD quality,
383 DWORD pitch, LPCWSTR name )
385 LOGFONTW logfont;
387 logfont.lfHeight = height;
388 logfont.lfWidth = width;
389 logfont.lfEscapement = esc;
390 logfont.lfOrientation = orient;
391 logfont.lfWeight = weight;
392 logfont.lfItalic = italic;
393 logfont.lfUnderline = underline;
394 logfont.lfStrikeOut = strikeout;
395 logfont.lfCharSet = charset;
396 logfont.lfOutPrecision = outpres;
397 logfont.lfClipPrecision = clippres;
398 logfont.lfQuality = quality;
399 logfont.lfPitchAndFamily = pitch;
401 if (name)
402 lstrcpynW(logfont.lfFaceName, name,
403 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
404 else
405 logfont.lfFaceName[0] = '\0';
407 return CreateFontIndirectW( &logfont );
411 /***********************************************************************
412 * FONT_SelectObject
414 * If the driver supports vector fonts we create a gdi font first and
415 * then call the driver to give it a chance to supply its own device
416 * font. If the driver wants to do this it returns TRUE and we can
417 * delete the gdi font, if the driver wants to use the gdi font it
418 * should return FALSE, to signal an error return GDI_ERROR. For
419 * drivers that don't support vector fonts they must supply their own
420 * font.
422 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
424 HGDIOBJ ret = 0;
425 DC *dc = DC_GetDCPtr( hdc );
427 if (!dc) return 0;
429 if (dc->hFont != handle || dc->gdiFont == NULL)
431 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
432 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
435 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
437 if (ret && dc->gdiFont) dc->gdiFont = 0;
439 if (ret == HGDI_ERROR)
440 ret = 0; /* SelectObject returns 0 on error */
441 else
443 ret = dc->hFont;
444 dc->hFont = handle;
446 GDI_ReleaseObj( hdc );
447 return ret;
451 /***********************************************************************
452 * FONT_GetObject16
454 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
456 FONTOBJ *font = obj;
457 LOGFONT16 lf16;
459 FONT_LogFontWTo16( &font->logfont, &lf16 );
461 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
462 memcpy( buffer, &lf16, count );
463 return count;
466 /***********************************************************************
467 * FONT_GetObjectA
469 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
471 FONTOBJ *font = obj;
472 LOGFONTA lfA;
474 FONT_LogFontWToA( &font->logfont, &lfA );
476 if (count > sizeof(lfA)) count = sizeof(lfA);
477 if(buffer)
478 memcpy( buffer, &lfA, count );
479 return count;
482 /***********************************************************************
483 * FONT_GetObjectW
485 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
487 FONTOBJ *font = obj;
488 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
489 if(buffer)
490 memcpy( buffer, &font->logfont, count );
491 return count;
495 /***********************************************************************
496 * FONT_DeleteObject
498 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
500 WineEngDestroyFontInstance( handle );
501 return GDI_FreeObject( handle, obj );
505 /***********************************************************************
506 * FONT_EnumInstance16
508 * Called by the device driver layer to pass font info
509 * down to the application.
511 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
512 DWORD fType, LPARAM lp )
514 fontEnum16 *pfe = (fontEnum16*)lp;
515 INT ret = 1;
516 DC *dc;
518 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
519 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
521 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
522 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
523 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
525 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
526 (UINT16)fType, (LPARAM)pfe->lpData );
527 /* get the lock again and make sure the DC is still valid */
528 dc = DC_GetDCPtr( pfe->hdc );
529 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
531 if (dc) GDI_ReleaseObj( pfe->hdc );
532 pfe->hdc = 0; /* make sure we don't try to release it later on */
533 ret = 0;
536 return ret;
539 /***********************************************************************
540 * FONT_EnumInstance
542 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
543 DWORD fType, LPARAM lp )
545 fontEnum32 *pfe = (fontEnum32*)lp;
546 INT ret = 1;
547 DC *dc;
549 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
550 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
551 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
553 /* convert font metrics */
554 ENUMLOGFONTEXA logfont;
555 NEWTEXTMETRICEXA tmA;
557 pfe->dwFlags |= ENUM_CALLED;
558 if (!(pfe->dwFlags & ENUM_UNICODE))
560 FONT_EnumLogFontExWToA( plf, &logfont);
561 FONT_NewTextMetricExWToA( ptm, &tmA );
562 plf = (LPENUMLOGFONTEXW)&logfont;
563 ptm = (NEWTEXTMETRICEXW *)&tmA;
565 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
567 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
569 /* get the lock again and make sure the DC is still valid */
570 dc = DC_GetDCPtr( pfe->hdc );
571 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
573 if (dc) GDI_ReleaseObj( pfe->hdc );
574 pfe->hdc = 0; /* make sure we don't try to release it later on */
575 ret = 0;
578 return ret;
581 /***********************************************************************
582 * EnumFontFamiliesEx (GDI.613)
584 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
585 FONTENUMPROC16 efproc, LPARAM lParam,
586 DWORD dwFlags)
588 fontEnum16 fe16;
589 INT16 retVal = 0;
590 DC* dc = DC_GetDCPtr( hDC );
592 if (!dc) return 0;
593 fe16.hdc = hDC;
594 fe16.dc = dc;
595 fe16.physDev = dc->physDev;
597 if (dc->funcs->pEnumDeviceFonts)
599 NEWTEXTMETRICEX16 tm16;
600 ENUMLOGFONTEX16 lf16;
601 LOGFONTW lfW;
602 FONT_LogFont16ToW(plf, &lfW);
604 fe16.lpLogFontParam = plf;
605 fe16.lpEnumFunc = efproc;
606 fe16.lpData = lParam;
607 fe16.lpTextMetric = &tm16;
608 fe16.lpLogFont = &lf16;
609 fe16.segTextMetric = MapLS( &tm16 );
610 fe16.segLogFont = MapLS( &lf16 );
612 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
613 FONT_EnumInstance16, (LPARAM)&fe16 );
614 UnMapLS( fe16.segTextMetric );
615 UnMapLS( fe16.segLogFont );
617 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
618 return retVal;
621 /***********************************************************************
622 * FONT_EnumFontFamiliesEx
624 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
625 FONTENUMPROCW efproc,
626 LPARAM lParam, DWORD dwUnicode)
628 INT ret = 1, ret2;
629 DC *dc = DC_GetDCPtr( hDC );
630 fontEnum32 fe32;
631 BOOL enum_gdi_fonts;
633 if (!dc) return 0;
635 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
636 plf->lfCharSet);
637 fe32.lpLogFontParam = plf;
638 fe32.lpEnumFunc = efproc;
639 fe32.lpData = lParam;
640 fe32.dwFlags = dwUnicode;
641 fe32.hdc = hDC;
642 fe32.dc = dc;
643 fe32.physDev = dc->physDev;
645 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
647 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
649 ret = 0;
650 goto done;
653 if (enum_gdi_fonts)
654 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
655 fe32.dwFlags &= ~ENUM_CALLED;
656 if (ret && dc->funcs->pEnumDeviceFonts) {
657 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
658 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
659 ret = ret2;
661 done:
662 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
663 return ret;
666 /***********************************************************************
667 * EnumFontFamiliesExW (GDI32.@)
669 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
670 FONTENUMPROCW efproc,
671 LPARAM lParam, DWORD dwFlags )
673 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
676 /***********************************************************************
677 * EnumFontFamiliesExA (GDI32.@)
679 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
680 FONTENUMPROCA efproc,
681 LPARAM lParam, DWORD dwFlags)
683 LOGFONTW lfW;
684 FONT_LogFontAToW( plf, &lfW );
686 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
689 /***********************************************************************
690 * EnumFontFamilies (GDI.330)
692 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
693 FONTENUMPROC16 efproc, LPARAM lpData )
695 LOGFONT16 lf;
697 lf.lfCharSet = DEFAULT_CHARSET;
698 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
699 else lf.lfFaceName[0] = '\0';
701 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
704 /***********************************************************************
705 * EnumFontFamiliesA (GDI32.@)
707 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
708 FONTENUMPROCA efproc, LPARAM lpData )
710 LOGFONTA lf;
712 lf.lfCharSet = DEFAULT_CHARSET;
713 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
714 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
716 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
719 /***********************************************************************
720 * EnumFontFamiliesW (GDI32.@)
722 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
723 FONTENUMPROCW efproc, LPARAM lpData )
725 LOGFONTW lf;
727 lf.lfCharSet = DEFAULT_CHARSET;
728 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
729 else lf.lfFaceName[0] = 0;
731 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
734 /***********************************************************************
735 * EnumFonts (GDI.70)
737 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
738 LPARAM lpData )
740 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
743 /***********************************************************************
744 * EnumFontsA (GDI32.@)
746 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
747 LPARAM lpData )
749 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
752 /***********************************************************************
753 * EnumFontsW (GDI32.@)
755 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
756 LPARAM lpData )
758 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
762 /***********************************************************************
763 * GetTextCharacterExtra (GDI32.@)
765 INT WINAPI GetTextCharacterExtra( HDC hdc )
767 INT ret;
768 DC *dc = DC_GetDCPtr( hdc );
769 if (!dc) return 0;
770 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
771 / dc->vportExtX );
772 GDI_ReleaseObj( hdc );
773 return ret;
777 /***********************************************************************
778 * SetTextCharacterExtra (GDI32.@)
780 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
782 INT prev;
783 DC * dc = DC_GetDCPtr( hdc );
784 if (!dc) return 0;
785 if (dc->funcs->pSetTextCharacterExtra)
786 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
787 else
789 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
790 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
791 dc->charExtra = abs(extra);
793 GDI_ReleaseObj( hdc );
794 return prev;
798 /***********************************************************************
799 * SetTextJustification (GDI32.@)
801 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
803 BOOL ret = TRUE;
804 DC * dc = DC_GetDCPtr( hdc );
805 if (!dc) return FALSE;
806 if (dc->funcs->pSetTextJustification)
807 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
808 else
810 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
811 if (!extra) breaks = 0;
812 dc->breakTotalExtra = extra;
813 dc->breakCount = breaks;
814 if (breaks)
816 dc->breakExtra = extra / breaks;
817 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
819 else
821 dc->breakExtra = 0;
822 dc->breakRem = 0;
825 GDI_ReleaseObj( hdc );
826 return ret;
830 /***********************************************************************
831 * GetTextFaceA (GDI32.@)
833 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
835 INT res = GetTextFaceW(hdc, 0, NULL);
836 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
837 GetTextFaceW( hdc, res, nameW );
839 if (name)
840 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
841 NULL, NULL);
842 else
843 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
844 HeapFree( GetProcessHeap(), 0, nameW );
845 return res;
848 /***********************************************************************
849 * GetTextFaceW (GDI32.@)
851 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
853 FONTOBJ *font;
854 INT ret = 0;
856 DC * dc = DC_GetDCPtr( hdc );
857 if (!dc) return 0;
859 if(dc->gdiFont)
860 ret = WineEngGetTextFace(dc->gdiFont, count, name);
861 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
863 if (name)
865 lstrcpynW( name, font->logfont.lfFaceName, count );
866 ret = strlenW(name);
868 else ret = strlenW(font->logfont.lfFaceName) + 1;
869 GDI_ReleaseObj( dc->hFont );
871 GDI_ReleaseObj( hdc );
872 return ret;
876 /***********************************************************************
877 * GetTextExtentPoint32A (GDI32.@)
879 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
880 LPSIZE size )
882 BOOL ret = FALSE;
883 INT wlen;
884 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
886 if (p) {
887 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
888 HeapFree( GetProcessHeap(), 0, p );
891 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
892 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
893 return ret;
897 /***********************************************************************
898 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
900 * Computes width and height of the specified string.
902 * RETURNS
903 * Success: TRUE
904 * Failure: FALSE
906 BOOL WINAPI GetTextExtentPoint32W(
907 HDC hdc, /* [in] Handle of device context */
908 LPCWSTR str, /* [in] Address of text string */
909 INT count, /* [in] Number of characters in string */
910 LPSIZE size) /* [out] Address of structure for string size */
912 BOOL ret = FALSE;
913 DC * dc = DC_GetDCPtr( hdc );
914 if (!dc) return FALSE;
916 if(dc->gdiFont) {
917 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
918 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
919 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
921 else if(dc->funcs->pGetTextExtentPoint)
922 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
924 GDI_ReleaseObj( hdc );
926 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
927 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
928 return ret;
931 /***********************************************************************
932 * GetTextExtentPointI [GDI32.@]
934 * Computes width and height of the array of glyph indices.
936 * RETURNS
937 * Success: TRUE
938 * Failure: FALSE
940 BOOL WINAPI GetTextExtentPointI(
941 HDC hdc, /* [in] Handle of device context */
942 const WORD *indices, /* [in] Address of glyph index array */
943 INT count, /* [in] Number of glyphs in array */
944 LPSIZE size) /* [out] Address of structure for string size */
946 BOOL ret = FALSE;
947 DC * dc = DC_GetDCPtr( hdc );
948 if (!dc) return FALSE;
950 if(dc->gdiFont) {
951 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
952 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
953 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
955 else if(dc->funcs->pGetTextExtentPoint) {
956 FIXME("calling GetTextExtentPoint\n");
957 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
960 GDI_ReleaseObj( hdc );
962 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
963 hdc, indices, count, size, size->cx, size->cy );
964 return ret;
968 /***********************************************************************
969 * GetTextExtentPointA (GDI32.@)
971 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
972 LPSIZE size )
974 TRACE("not bug compatible.\n");
975 return GetTextExtentPoint32A( hdc, str, count, size );
978 /***********************************************************************
979 * GetTextExtentPointW (GDI32.@)
981 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
982 LPSIZE size )
984 TRACE("not bug compatible.\n");
985 return GetTextExtentPoint32W( hdc, str, count, size );
989 /***********************************************************************
990 * GetTextExtentExPointA (GDI32.@)
992 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
993 INT maxExt, LPINT lpnFit,
994 LPINT alpDx, LPSIZE size )
996 BOOL ret;
997 INT wlen;
998 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
999 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1000 HeapFree( GetProcessHeap(), 0, p );
1001 return ret;
1005 /***********************************************************************
1006 * GetTextExtentExPointW (GDI32.@)
1008 * Return the size of the string as it would be if it was output properly by
1009 * e.g. TextOut.
1011 * This should include
1012 * - Intercharacter spacing
1013 * - justification spacing (not yet done)
1014 * - kerning? see below
1016 * Kerning. Since kerning would be carried out by the rendering code it should
1017 * be done by the driver. However they don't support it yet. Also I am not
1018 * yet persuaded that (certainly under Win95) any kerning is actually done.
1020 * str: According to MSDN this should be null-terminated. That is not true; a
1021 * null will not terminate it early.
1022 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1023 * than count. I have seen it be either the size of the full string or
1024 * 1 less than the size of the full string. I have not seen it bear any
1025 * resemblance to the portion that would fit.
1026 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1027 * trailing intercharacter spacing and any trailing justification.
1029 * FIXME
1030 * Currently we do this by measuring each character etc. We should do it by
1031 * passing the request to the driver, perhaps by extending the
1032 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1033 * thinking about kerning issues and rounding issues in the justification.
1036 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1037 INT maxExt, LPINT lpnFit,
1038 LPINT alpDx, LPSIZE size )
1040 int index, nFit, extent;
1041 SIZE tSize;
1042 BOOL ret = FALSE;
1044 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1046 size->cx = size->cy = nFit = extent = 0;
1047 for(index = 0; index < count; index++)
1049 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1050 /* GetTextExtentPoint includes intercharacter spacing. */
1051 /* FIXME - justification needs doing yet. Remember that the base
1052 * data will not be in logical coordinates.
1054 extent += tSize.cx;
1055 if( !lpnFit || extent <= maxExt )
1056 /* It is allowed to be equal. */
1058 nFit++;
1059 if( alpDx ) alpDx[index] = extent;
1061 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1062 str++;
1064 size->cx = extent;
1065 if(lpnFit) *lpnFit = nFit;
1066 ret = TRUE;
1068 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1070 done:
1071 return ret;
1074 /***********************************************************************
1075 * GetTextMetricsA (GDI32.@)
1077 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1079 TEXTMETRICW tm32;
1081 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1082 FONT_TextMetricWToA( &tm32, metrics );
1083 return TRUE;
1086 /***********************************************************************
1087 * GetTextMetricsW (GDI32.@)
1089 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1091 BOOL ret = FALSE;
1092 DC * dc = DC_GetDCPtr( hdc );
1093 if (!dc) return FALSE;
1095 if (dc->gdiFont)
1096 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1097 else if (dc->funcs->pGetTextMetrics)
1098 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1100 if (ret)
1102 /* device layer returns values in device units
1103 * therefore we have to convert them to logical */
1105 #define WDPTOLP(x) ((x<0)? \
1106 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1107 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1108 #define HDPTOLP(y) ((y<0)? \
1109 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1110 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1112 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1113 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1114 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1115 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1116 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1117 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1118 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1119 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1120 ret = TRUE;
1121 #undef WDPTOLP
1122 #undef HDPTOLP
1123 TRACE("text metrics:\n"
1124 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1125 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1126 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1127 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1128 " PitchAndFamily = %02x\n"
1129 " --------------------\n"
1130 " InternalLeading = %li\n"
1131 " Ascent = %li\n"
1132 " Descent = %li\n"
1133 " Height = %li\n",
1134 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1135 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1136 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1137 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1138 metrics->tmPitchAndFamily,
1139 metrics->tmInternalLeading,
1140 metrics->tmAscent,
1141 metrics->tmDescent,
1142 metrics->tmHeight );
1144 GDI_ReleaseObj( hdc );
1145 return ret;
1149 /***********************************************************************
1150 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1152 * NOTES
1153 * lpOTM should be LPOUTLINETEXTMETRIC
1155 * RETURNS
1156 * Success: Non-zero or size of required buffer
1157 * Failure: 0
1159 UINT16 WINAPI GetOutlineTextMetrics16(
1160 HDC16 hdc, /* [in] Handle of device context */
1161 UINT16 cbData, /* [in] Size of metric data array */
1162 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1164 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1165 return 0;
1169 /***********************************************************************
1170 * GetOutlineTextMetricsA (GDI32.@)
1171 * Gets metrics for TrueType fonts.
1174 * RETURNS
1175 * Success: Non-zero or size of required buffer
1176 * Failure: 0
1178 UINT WINAPI GetOutlineTextMetricsA(
1179 HDC hdc, /* [in] Handle of device context */
1180 UINT cbData, /* [in] Size of metric data array */
1181 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1183 char buf[512], *ptr;
1184 UINT ret, needed;
1185 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1186 INT left, len;
1188 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1189 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1190 return 0;
1191 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1192 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1195 needed = sizeof(OUTLINETEXTMETRICA);
1196 if(lpOTMW->otmpFamilyName)
1197 needed += WideCharToMultiByte(CP_ACP, 0,
1198 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1199 NULL, 0, NULL, NULL);
1200 if(lpOTMW->otmpFaceName)
1201 needed += WideCharToMultiByte(CP_ACP, 0,
1202 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1203 NULL, 0, NULL, NULL);
1204 if(lpOTMW->otmpStyleName)
1205 needed += WideCharToMultiByte(CP_ACP, 0,
1206 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1207 NULL, 0, NULL, NULL);
1208 if(lpOTMW->otmpFullName)
1209 needed += WideCharToMultiByte(CP_ACP, 0,
1210 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1211 NULL, 0, NULL, NULL);
1213 if(!lpOTM) {
1214 ret = needed;
1215 goto end;
1218 if(needed > cbData) {
1219 ret = 0;
1220 goto end;
1224 lpOTM->otmSize = needed;
1225 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1226 lpOTM->otmFiller = 0;
1227 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1228 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1229 lpOTM->otmfsType = lpOTMW->otmfsType;
1230 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1231 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1232 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1233 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1234 lpOTM->otmAscent = lpOTMW->otmAscent;
1235 lpOTM->otmDescent = lpOTMW->otmDescent;
1236 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1237 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1238 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1239 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1240 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1241 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1242 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1243 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1244 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1245 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1246 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1247 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1248 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1249 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1250 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1251 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1254 ptr = (char*)(lpOTM + 1);
1255 left = needed - sizeof(*lpOTM);
1257 if(lpOTMW->otmpFamilyName) {
1258 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1259 len = WideCharToMultiByte(CP_ACP, 0,
1260 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1261 ptr, left, NULL, NULL);
1262 left -= len;
1263 ptr += len;
1264 } else
1265 lpOTM->otmpFamilyName = 0;
1267 if(lpOTMW->otmpFaceName) {
1268 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1269 len = WideCharToMultiByte(CP_ACP, 0,
1270 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1271 ptr, left, NULL, NULL);
1272 left -= len;
1273 ptr += len;
1274 } else
1275 lpOTM->otmpFaceName = 0;
1277 if(lpOTMW->otmpStyleName) {
1278 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1279 len = WideCharToMultiByte(CP_ACP, 0,
1280 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1281 ptr, left, NULL, NULL);
1282 left -= len;
1283 ptr += len;
1284 } else
1285 lpOTM->otmpStyleName = 0;
1287 if(lpOTMW->otmpFullName) {
1288 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1289 len = WideCharToMultiByte(CP_ACP, 0,
1290 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1291 ptr, left, NULL, NULL);
1292 left -= len;
1293 } else
1294 lpOTM->otmpFullName = 0;
1296 assert(left == 0);
1298 ret = needed;
1300 end:
1301 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1302 HeapFree(GetProcessHeap(), 0, lpOTMW);
1304 return ret;
1308 /***********************************************************************
1309 * GetOutlineTextMetricsW [GDI32.@]
1311 UINT WINAPI GetOutlineTextMetricsW(
1312 HDC hdc, /* [in] Handle of device context */
1313 UINT cbData, /* [in] Size of metric data array */
1314 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1316 DC *dc = DC_GetDCPtr( hdc );
1317 UINT ret;
1319 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1320 if(!dc) return 0;
1322 if(dc->gdiFont) {
1323 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1324 if(ret && ret <= cbData) {
1325 #define WDPTOLP(x) ((x<0)? \
1326 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1327 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1328 #define HDPTOLP(y) ((y<0)? \
1329 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1330 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1332 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1333 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1334 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1335 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1336 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1337 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1338 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1339 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1340 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1341 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1342 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1343 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1344 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1345 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1346 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1347 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1348 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1349 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1350 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1351 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1352 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1353 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1354 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1355 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1356 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1357 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1358 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1359 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1360 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1361 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1362 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1363 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1364 #undef WDPTOLP
1365 #undef HDPTOLP
1369 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1370 but really this should just be a return 0. */
1372 ret = sizeof(*lpOTM);
1373 if (lpOTM) {
1374 if(cbData < ret)
1375 ret = 0;
1376 else {
1377 memset(lpOTM, 0, ret);
1378 lpOTM->otmSize = sizeof(*lpOTM);
1379 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1381 Further fill of the structure not implemented,
1382 Needs real values for the structure members
1387 GDI_ReleaseObj(hdc);
1388 return ret;
1392 /***********************************************************************
1393 * GetCharWidthW (GDI32.@)
1394 * GetCharWidth32W (GDI32.@)
1396 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1397 LPINT buffer )
1399 UINT i, extra;
1400 BOOL ret = FALSE;
1401 DC * dc = DC_GetDCPtr( hdc );
1402 if (!dc) return FALSE;
1404 if (dc->gdiFont)
1405 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1406 else if (dc->funcs->pGetCharWidth)
1407 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1409 if (ret)
1411 /* convert device units to logical */
1413 extra = dc->vportExtX >> 1;
1414 for( i = firstChar; i <= lastChar; i++, buffer++ )
1415 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1416 ret = TRUE;
1418 GDI_ReleaseObj( hdc );
1419 return ret;
1423 /***********************************************************************
1424 * GetCharWidthA (GDI32.@)
1425 * GetCharWidth32A (GDI32.@)
1427 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1428 LPINT buffer )
1430 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1431 LPSTR str;
1432 LPWSTR wstr;
1433 BOOL ret = TRUE;
1435 if(count <= 0) return FALSE;
1437 str = HeapAlloc(GetProcessHeap(), 0, count);
1438 for(i = 0; i < count; i++)
1439 str[i] = (BYTE)(firstChar + i);
1441 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1443 for(i = 0; i < wlen; i++)
1445 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1447 ret = FALSE;
1448 break;
1450 buffer++;
1453 HeapFree(GetProcessHeap(), 0, str);
1454 HeapFree(GetProcessHeap(), 0, wstr);
1456 return ret;
1460 /* FIXME: all following APIs ******************************************/
1463 /***********************************************************************
1464 * SetMapperFlags (GDI32.@)
1466 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1468 DC *dc = DC_GetDCPtr( hDC );
1469 DWORD ret = 0;
1470 if(!dc) return 0;
1471 if(dc->funcs->pSetMapperFlags)
1472 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1473 else
1474 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1475 GDI_ReleaseObj( hDC );
1476 return ret;
1479 /***********************************************************************
1480 * GetAspectRatioFilterEx (GDI.486)
1482 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1484 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1485 return FALSE;
1488 /***********************************************************************
1489 * GetAspectRatioFilterEx (GDI32.@)
1491 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1493 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1494 return FALSE;
1498 /***********************************************************************
1499 * GetCharABCWidthsA (GDI32.@)
1501 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1502 LPABC abc )
1504 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1505 LPSTR str;
1506 LPWSTR wstr;
1507 BOOL ret = TRUE;
1509 if(count <= 0) return FALSE;
1511 str = HeapAlloc(GetProcessHeap(), 0, count);
1512 for(i = 0; i < count; i++)
1513 str[i] = (BYTE)(firstChar + i);
1515 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1517 for(i = 0; i < wlen; i++)
1519 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1521 ret = FALSE;
1522 break;
1524 abc++;
1527 HeapFree(GetProcessHeap(), 0, str);
1528 HeapFree(GetProcessHeap(), 0, wstr);
1530 return ret;
1534 /******************************************************************************
1535 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1537 * PARAMS
1538 * hdc [I] Handle of device context
1539 * firstChar [I] First character in range to query
1540 * lastChar [I] Last character in range to query
1541 * abc [O] Address of character-width structure
1543 * NOTES
1544 * Only works with TrueType fonts
1546 * RETURNS
1547 * Success: TRUE
1548 * Failure: FALSE
1550 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1551 LPABC abc )
1553 DC *dc = DC_GetDCPtr(hdc);
1554 int i;
1555 GLYPHMETRICS gm;
1556 BOOL ret = FALSE;
1558 if(dc->gdiFont) {
1559 for (i=firstChar;i<=lastChar;i++) {
1560 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1561 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1562 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1563 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1565 ret = TRUE;
1567 GDI_ReleaseObj(hdc);
1568 return ret;
1572 /***********************************************************************
1573 * GetGlyphOutline (GDI.309)
1575 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1576 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1577 LPVOID lpBuffer, const MAT2 *lpmat2 )
1579 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1580 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1581 return (DWORD)-1; /* failure */
1585 /***********************************************************************
1586 * GetGlyphOutlineA (GDI32.@)
1588 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1589 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1590 LPVOID lpBuffer, const MAT2 *lpmat2 )
1592 LPWSTR p = NULL;
1593 DWORD ret;
1594 UINT c;
1596 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1597 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1598 c = p[0];
1599 } else
1600 c = uChar;
1601 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1602 lpmat2);
1603 if(p)
1604 HeapFree(GetProcessHeap(), 0, p);
1605 return ret;
1608 /***********************************************************************
1609 * GetGlyphOutlineW (GDI32.@)
1611 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1612 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1613 LPVOID lpBuffer, const MAT2 *lpmat2 )
1615 DC *dc = DC_GetDCPtr(hdc);
1616 DWORD ret;
1618 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1619 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1621 if(!dc) return GDI_ERROR;
1623 if(dc->gdiFont)
1624 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1625 cbBuffer, lpBuffer, lpmat2);
1626 else
1627 ret = GDI_ERROR;
1629 GDI_ReleaseObj(hdc);
1630 return ret;
1634 /***********************************************************************
1635 * CreateScalableFontResourceA (GDI32.@)
1637 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1638 LPCSTR lpszResourceFile,
1639 LPCSTR lpszFontFile,
1640 LPCSTR lpszCurrentPath )
1642 HANDLE f;
1644 /* fHidden=1 - only visible for the calling app, read-only, not
1645 * enumbered with EnumFonts/EnumFontFamilies
1646 * lpszCurrentPath can be NULL
1648 FIXME("(%ld,%s,%s,%s): stub\n",
1649 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1650 debugstr_a(lpszCurrentPath) );
1652 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1653 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1654 CloseHandle(f);
1655 SetLastError(ERROR_FILE_EXISTS);
1656 return FALSE;
1658 return FALSE; /* create failed */
1661 /***********************************************************************
1662 * CreateScalableFontResourceW (GDI32.@)
1664 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1665 LPCWSTR lpszResourceFile,
1666 LPCWSTR lpszFontFile,
1667 LPCWSTR lpszCurrentPath )
1669 FIXME("(%ld,%p,%p,%p): stub\n",
1670 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1671 return FALSE; /* create failed */
1675 /*************************************************************************
1676 * GetRasterizerCaps (GDI32.@)
1678 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1680 lprs->nSize = sizeof(RASTERIZER_STATUS);
1681 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1682 lprs->nLanguageID = 0;
1683 return TRUE;
1687 /*************************************************************************
1688 * GetKerningPairsA (GDI32.@)
1690 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1692 int i;
1693 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1694 for (i = 0; i < cPairs; i++)
1695 lpKerningPairs[i].iKernAmount = 0;
1696 return 0;
1700 /*************************************************************************
1701 * GetKerningPairsW (GDI32.@)
1703 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1704 LPKERNINGPAIR lpKerningPairs )
1706 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1709 /*************************************************************************
1710 * TranslateCharsetInfo [GDI32.@]
1712 * Fills a CHARSETINFO structure for a character set, code page, or
1713 * font. This allows making the correspondance between different labelings
1714 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1715 * of the same encoding.
1717 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1718 * only one codepage should be set in *lpSrc.
1720 * RETURNS
1721 * TRUE on success, FALSE on failure.
1724 BOOL WINAPI TranslateCharsetInfo(
1725 LPDWORD lpSrc, /* [in]
1726 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1727 if flags == TCI_SRCCHARSET: a character set value
1728 if flags == TCI_SRCCODEPAGE: a code page value
1730 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1731 DWORD flags /* [in] determines interpretation of lpSrc */
1733 int index = 0;
1734 switch (flags) {
1735 case TCI_SRCFONTSIG:
1736 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1737 break;
1738 case TCI_SRCCODEPAGE:
1739 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1740 break;
1741 case TCI_SRCCHARSET:
1742 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1743 break;
1744 default:
1745 return FALSE;
1747 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1748 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1749 return TRUE;
1752 /*************************************************************************
1753 * GetFontLanguageInfo (GDI32.@)
1755 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1757 FONTSIGNATURE fontsig;
1758 static const DWORD GCP_DBCS_MASK=0x003F0000,
1759 GCP_DIACRITIC_MASK=0x00000000,
1760 FLI_GLYPHS_MASK=0x00000000,
1761 GCP_GLYPHSHAPE_MASK=0x00000040,
1762 GCP_KASHIDA_MASK=0x00000000,
1763 GCP_LIGATE_MASK=0x00000000,
1764 GCP_USEKERNING_MASK=0x00000000,
1765 GCP_REORDER_MASK=0x00000060;
1767 DWORD result=0;
1769 GetTextCharsetInfo( hdc, &fontsig, 0 );
1770 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1772 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1773 result|=GCP_DBCS;
1775 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1776 result|=GCP_DIACRITIC;
1778 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1779 result|=FLI_GLYPHS;
1781 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1782 result|=GCP_GLYPHSHAPE;
1784 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1785 result|=GCP_KASHIDA;
1787 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1788 result|=GCP_LIGATE;
1790 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1791 result|=GCP_USEKERNING;
1793 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1794 result|=GCP_REORDER;
1796 return result;
1800 /*************************************************************************
1801 * GetFontData [GDI32.@] Retrieve data for TrueType font
1803 * RETURNS
1805 * success: Number of bytes returned
1806 * failure: GDI_ERROR
1808 * NOTES
1810 * Calls SetLastError()
1813 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1814 LPVOID buffer, DWORD length)
1816 DC *dc = DC_GetDCPtr(hdc);
1817 DWORD ret = GDI_ERROR;
1819 if(!dc) return GDI_ERROR;
1821 if(dc->gdiFont)
1822 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1824 GDI_ReleaseObj(hdc);
1825 return ret;
1828 /*************************************************************************
1829 * GetGlyphIndicesA [GDI32.@]
1831 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1832 LPWORD pgi, DWORD flags)
1834 DWORD ret;
1835 WCHAR *lpstrW;
1836 INT countW;
1838 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1839 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1841 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1842 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1843 HeapFree(GetProcessHeap(), 0, lpstrW);
1845 return ret;
1848 /*************************************************************************
1849 * GetGlyphIndicesW [GDI32.@]
1851 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1852 LPWORD pgi, DWORD flags)
1854 DC *dc = DC_GetDCPtr(hdc);
1855 DWORD ret = GDI_ERROR;
1857 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1858 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1860 if(!dc) return GDI_ERROR;
1862 if(dc->gdiFont)
1863 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1865 GDI_ReleaseObj(hdc);
1866 return ret;
1869 /*************************************************************************
1870 * GetCharacterPlacementA [GDI32.@]
1872 * NOTES:
1873 * the web browser control of ie4 calls this with dwFlags=0
1875 DWORD WINAPI
1876 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1877 INT nMaxExtent, GCP_RESULTSA *lpResults,
1878 DWORD dwFlags)
1880 WCHAR *lpStringW;
1881 INT uCountW, i;
1882 GCP_RESULTSW resultsW;
1883 DWORD ret;
1884 UINT font_cp;
1886 TRACE("%s, %d, %d, 0x%08lx\n",
1887 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1889 /* both structs are equal in size */
1890 memcpy(&resultsW, lpResults, sizeof(resultsW));
1892 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1893 if(lpResults->lpOutString)
1894 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1896 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1898 if(lpResults->lpOutString) {
1899 if(font_cp != CP_SYMBOL)
1900 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1901 lpResults->lpOutString, uCount, NULL, NULL );
1902 else
1903 for(i = 0; i < uCount; i++)
1904 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1907 HeapFree(GetProcessHeap(), 0, lpStringW);
1908 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1910 return ret;
1913 /*************************************************************************
1914 * GetCharacterPlacementW [GDI32.@]
1916 * Retrieve information about a string. This includes the width, reordering,
1917 * Glyphing and so on.
1919 * RETURNS
1921 * The width and height of the string if succesful, 0 if failed.
1923 * BUGS
1925 * All flags except GCP_REORDER are not yet implemented.
1926 * Reordering is not 100% complient to the Windows BiDi method.
1927 * Caret positioning is not yet implemented.
1928 * Classes are not yet implemented.
1931 DWORD WINAPI
1932 GetCharacterPlacementW(
1933 HDC hdc, /* [in] Device context for which the rendering is to be done */
1934 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1935 INT uCount, /* [in] Number of WORDS in string. */
1936 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1937 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1938 DWORD dwFlags /* [in] Flags specifying how to process the string */
1941 DWORD ret=0;
1942 SIZE size;
1943 UINT i, nSet;
1945 TRACE("%s, %d, %d, 0x%08lx\n",
1946 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1948 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1949 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1950 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1951 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1952 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1954 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1955 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1956 if(lpResults->lpClass) FIXME("classes not implemented\n");
1958 nSet = (UINT)uCount;
1959 if(nSet > lpResults->nGlyphs)
1960 nSet = lpResults->nGlyphs;
1962 /* return number of initialized fields */
1963 lpResults->nGlyphs = nSet;
1965 if(dwFlags==0)
1967 /* Treat the case where no special handling was requested in a fastpath way */
1968 /* copy will do if the GCP_REORDER flag is not set */
1969 if(lpResults->lpOutString)
1970 for(i=0; i<nSet && lpString[i]!=0; ++i )
1971 lpResults->lpOutString[i]=lpString[i];
1973 if(lpResults->lpOrder)
1975 for(i = 0; i < nSet; i++)
1976 lpResults->lpOrder[i] = i;
1980 if((dwFlags&GCP_REORDER)!=0)
1982 WORD *pwCharType;
1983 int run_end;
1984 /* Keep a static table that translates the C2 types to something meaningful */
1985 /* 1 - left to right
1986 * -1 - right to left
1987 * 0 - neutral
1989 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
1991 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
1992 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
1994 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1996 return 0;
1999 /* Fill in the order array with directionality values */
2000 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2002 /* The complete and correct (at least according to MS) BiDi algorythm is not
2003 * yet implemented here. Instead, we just make sure that consecutive runs of
2004 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2005 * that are between runs of opposing directions the base (ok, always LTR) dir.
2006 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2007 * readable results.
2009 for( i=0; i<uCount; i+=run_end )
2011 for( run_end=1; i+run_end<uCount &&
2012 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2013 chardir[pwCharType[i+run_end]]==0); ++run_end )
2016 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2018 /* A LTR run */
2019 if(lpResults->lpOutString)
2021 int j;
2022 for( j=0; j<run_end; j++ )
2024 lpResults->lpOutString[i+j]=lpString[i+j];
2028 if(lpResults->lpOrder)
2030 int j;
2031 for( j=0; j<run_end; j++ )
2032 lpResults->lpOrder[i+j] = i+j;
2034 } else
2036 /* A RTL run */
2038 /* Since, at this stage, the paragraph context is always LTR,
2039 * remove any neutrals from the end of this run.
2041 if( chardir[pwCharType[i]]!=0 )
2042 while( chardir[pwCharType[i+run_end-1]]==0 )
2043 --run_end;
2045 if(lpResults->lpOutString)
2047 int j;
2048 for( j=0; j<run_end; j++ )
2050 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2054 if(lpResults->lpOrder)
2056 int j;
2057 for( j=0; j<run_end; j++ )
2058 lpResults->lpOrder[i+j] = i+run_end-j-1;
2063 HeapFree(GetProcessHeap(), 0, pwCharType);
2066 /* FIXME: Will use the placement chars */
2067 if (lpResults->lpDx)
2069 int c;
2070 for (i = 0; i < nSet; i++)
2072 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2073 lpResults->lpDx[i]= c;
2077 if(lpResults->lpGlyphs)
2078 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2080 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2081 ret = MAKELONG(size.cx, size.cy);
2083 return ret;
2086 /*************************************************************************
2087 * GetCharABCWidthsFloatA [GDI32.@]
2089 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2090 LPABCFLOAT lpABCF)
2092 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2093 return 0;
2096 /*************************************************************************
2097 * GetCharABCWidthsFloatW [GDI32.@]
2099 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2100 UINT iLastChar, LPABCFLOAT lpABCF)
2102 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2103 return 0;
2106 /*************************************************************************
2107 * GetCharWidthFloatA [GDI32.@]
2109 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2110 UINT iLastChar, PFLOAT pxBuffer)
2112 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2113 return 0;
2116 /*************************************************************************
2117 * GetCharWidthFloatW [GDI32.@]
2119 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2120 UINT iLastChar, PFLOAT pxBuffer)
2122 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2123 return 0;
2127 /***********************************************************************
2129 * Font Resource API *
2131 ***********************************************************************/
2133 /***********************************************************************
2134 * AddFontResourceA (GDI32.@)
2136 INT WINAPI AddFontResourceA( LPCSTR str )
2138 return AddFontResourceExA( str, 0, NULL);
2141 /***********************************************************************
2142 * AddFontResourceW (GDI32.@)
2144 INT WINAPI AddFontResourceW( LPCWSTR str )
2146 return AddFontResourceExW(str, 0, NULL);
2150 /***********************************************************************
2151 * AddFontResourceExA (GDI32.@)
2153 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2155 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2156 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2157 INT ret;
2159 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2160 ret = AddFontResourceExW(strW, fl, pdv);
2161 HeapFree(GetProcessHeap(), 0, strW);
2162 return ret;
2165 /***********************************************************************
2166 * AddFontResourceExW (GDI32.@)
2168 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2170 return WineEngAddFontResourceEx(str, fl, pdv);
2173 /***********************************************************************
2174 * RemoveFontResourceA (GDI32.@)
2176 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2178 return RemoveFontResourceExA(str, 0, 0);
2181 /***********************************************************************
2182 * RemoveFontResourceW (GDI32.@)
2184 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2186 return RemoveFontResourceExW(str, 0, 0);
2189 /***********************************************************************
2190 * RemoveFontResourceExA (GDI32.@)
2192 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2194 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2195 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2196 INT ret;
2198 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2199 ret = RemoveFontResourceExW(strW, fl, pdv);
2200 HeapFree(GetProcessHeap(), 0, strW);
2201 return ret;
2204 /***********************************************************************
2205 * RemoveFontResourceExW (GDI32.@)
2207 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2209 return WineEngRemoveFontResourceEx(str, fl, pdv);