Converted implementation of _lseek to _lseeki64, implemented _lseek by
[wine/wine64.git] / objects / font.c
blobbbbe27fefd431986a0b92c0594e4436dca8a2100
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 "wownt32.h"
31 #include "wine/unicode.h"
32 #include "font.h"
33 #include "wine/debug.h"
34 #include "gdi.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 HDC hdc;
75 DC *dc;
76 PHYSDEV physDev;
77 } fontEnum16;
79 typedef struct
81 LPLOGFONTW lpLogFontParam;
82 FONTENUMPROCW lpEnumFunc;
83 LPARAM lpData;
84 DWORD dwFlags;
85 HDC hdc;
86 DC *dc;
87 PHYSDEV physDev;
88 } fontEnum32;
91 * For TranslateCharsetInfo
93 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
94 #define MAXTCIINDEX 32
95 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
96 /* ANSI */
97 { ANSI_CHARSET, 1252, FS(0)},
98 { EASTEUROPE_CHARSET, 1250, FS(1)},
99 { RUSSIAN_CHARSET, 1251, FS(2)},
100 { GREEK_CHARSET, 1253, FS(3)},
101 { TURKISH_CHARSET, 1254, FS(4)},
102 { HEBREW_CHARSET, 1255, FS(5)},
103 { ARABIC_CHARSET, 1256, FS(6)},
104 { BALTIC_CHARSET, 1257, FS(7)},
105 { VIETNAMESE_CHARSET, 1258, FS(8)},
106 /* reserved by ANSI */
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 { DEFAULT_CHARSET, 0, FS(0)},
114 /* ANSI and OEM */
115 { THAI_CHARSET, 874, FS(16)},
116 { SHIFTJIS_CHARSET, 932, FS(17)},
117 { GB2312_CHARSET, 936, FS(18)},
118 { HANGEUL_CHARSET, 949, FS(19)},
119 { CHINESEBIG5_CHARSET, 950, FS(20)},
120 { JOHAB_CHARSET, 1361, FS(21)},
121 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
130 /* reserved for system */
131 { DEFAULT_CHARSET, 0, FS(0)},
132 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
135 /* ### start build ### */
136 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROC16,LONG,LONG,WORD,LONG);
137 /* ### stop build ### */
139 /***********************************************************************
140 * LOGFONT conversion functions.
142 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
144 font16->lfHeight = font32->lfHeight;
145 font16->lfWidth = font32->lfWidth;
146 font16->lfEscapement = font32->lfEscapement;
147 font16->lfOrientation = font32->lfOrientation;
148 font16->lfWeight = font32->lfWeight;
149 font16->lfItalic = font32->lfItalic;
150 font16->lfUnderline = font32->lfUnderline;
151 font16->lfStrikeOut = font32->lfStrikeOut;
152 font16->lfCharSet = font32->lfCharSet;
153 font16->lfOutPrecision = font32->lfOutPrecision;
154 font16->lfClipPrecision = font32->lfClipPrecision;
155 font16->lfQuality = font32->lfQuality;
156 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
157 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
158 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
159 font16->lfFaceName[LF_FACESIZE-1] = 0;
162 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
164 font32->lfHeight = font16->lfHeight;
165 font32->lfWidth = font16->lfWidth;
166 font32->lfEscapement = font16->lfEscapement;
167 font32->lfOrientation = font16->lfOrientation;
168 font32->lfWeight = font16->lfWeight;
169 font32->lfItalic = font16->lfItalic;
170 font32->lfUnderline = font16->lfUnderline;
171 font32->lfStrikeOut = font16->lfStrikeOut;
172 font32->lfCharSet = font16->lfCharSet;
173 font32->lfOutPrecision = font16->lfOutPrecision;
174 font32->lfClipPrecision = font16->lfClipPrecision;
175 font32->lfQuality = font16->lfQuality;
176 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
177 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
178 font32->lfFaceName[LF_FACESIZE-1] = 0;
181 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
183 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
184 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
185 LF_FACESIZE);
188 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
190 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
191 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
192 LF_FACESIZE, NULL, NULL);
195 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
197 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
199 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
200 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
201 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
202 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
203 font16->elfStyle, LF_FACESIZE, NULL, NULL );
204 font16->elfStyle[LF_FACESIZE-1] = '\0';
205 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
206 font16->elfScript, LF_FACESIZE, NULL, NULL );
207 font16->elfScript[LF_FACESIZE-1] = '\0';
210 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
212 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
214 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
215 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
216 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
217 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
218 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
219 fontA->elfStyle[LF_FACESIZE-1] = '\0';
220 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
221 fontA->elfScript, LF_FACESIZE, NULL, NULL );
222 fontA->elfScript[LF_FACESIZE-1] = '\0';
225 /***********************************************************************
226 * TEXTMETRIC conversion functions.
228 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
230 ptmA->tmHeight = ptmW->tmHeight;
231 ptmA->tmAscent = ptmW->tmAscent;
232 ptmA->tmDescent = ptmW->tmDescent;
233 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
234 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
235 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
236 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
237 ptmA->tmWeight = ptmW->tmWeight;
238 ptmA->tmOverhang = ptmW->tmOverhang;
239 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
240 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
241 ptmA->tmFirstChar = ptmW->tmFirstChar;
242 ptmA->tmLastChar = ptmW->tmLastChar;
243 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
244 ptmA->tmBreakChar = ptmW->tmBreakChar;
245 ptmA->tmItalic = ptmW->tmItalic;
246 ptmA->tmUnderlined = ptmW->tmUnderlined;
247 ptmA->tmStruckOut = ptmW->tmStruckOut;
248 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
249 ptmA->tmCharSet = ptmW->tmCharSet;
253 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
255 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
256 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
257 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
258 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
259 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
260 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
261 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
262 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
263 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
264 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
265 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
266 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar;
267 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar;
268 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar;
269 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar;
270 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
271 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
272 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
273 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
274 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
275 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
276 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
277 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
278 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
279 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
282 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
284 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
285 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
286 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
287 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
288 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
289 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
292 /***********************************************************************
293 * CreateFontIndirectA (GDI32.@)
295 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
297 LOGFONTW lfW;
299 if (plfA) {
300 FONT_LogFontAToW( plfA, &lfW );
301 return CreateFontIndirectW( &lfW );
302 } else
303 return CreateFontIndirectW( NULL );
307 /***********************************************************************
308 * CreateFontIndirectW (GDI32.@)
310 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
312 HFONT hFont = 0;
314 if (plf)
316 FONTOBJ* fontPtr;
317 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
318 (HGDIOBJ *)&hFont, &font_funcs )))
320 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
322 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s => %p\n",
323 plf->lfHeight, plf->lfWidth,
324 plf->lfEscapement, plf->lfOrientation,
325 plf->lfPitchAndFamily,
326 plf->lfOutPrecision, plf->lfClipPrecision,
327 plf->lfQuality, plf->lfCharSet,
328 debugstr_w(plf->lfFaceName),
329 plf->lfWeight > 400 ? "Bold" : "",
330 plf->lfItalic ? "Italic" : "", hFont);
332 if (plf->lfEscapement != plf->lfOrientation) {
333 /* this should really depend on whether GM_ADVANCED is set */
334 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
335 WARN("orientation angle %f set to "
336 "escapement angle %f for new font %p\n",
337 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
339 GDI_ReleaseObj( hFont );
342 else WARN("(NULL) => NULL\n");
344 return hFont;
347 /*************************************************************************
348 * CreateFontA (GDI32.@)
350 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
351 INT orient, INT weight, DWORD italic,
352 DWORD underline, DWORD strikeout, DWORD charset,
353 DWORD outpres, DWORD clippres, DWORD quality,
354 DWORD pitch, LPCSTR name )
356 LOGFONTA logfont;
358 logfont.lfHeight = height;
359 logfont.lfWidth = width;
360 logfont.lfEscapement = esc;
361 logfont.lfOrientation = orient;
362 logfont.lfWeight = weight;
363 logfont.lfItalic = italic;
364 logfont.lfUnderline = underline;
365 logfont.lfStrikeOut = strikeout;
366 logfont.lfCharSet = charset;
367 logfont.lfOutPrecision = outpres;
368 logfont.lfClipPrecision = clippres;
369 logfont.lfQuality = quality;
370 logfont.lfPitchAndFamily = pitch;
372 if (name)
373 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
374 else
375 logfont.lfFaceName[0] = '\0';
377 return CreateFontIndirectA( &logfont );
380 /*************************************************************************
381 * CreateFontW (GDI32.@)
383 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
384 INT orient, INT weight, DWORD italic,
385 DWORD underline, DWORD strikeout, DWORD charset,
386 DWORD outpres, DWORD clippres, DWORD quality,
387 DWORD pitch, LPCWSTR name )
389 LOGFONTW logfont;
391 logfont.lfHeight = height;
392 logfont.lfWidth = width;
393 logfont.lfEscapement = esc;
394 logfont.lfOrientation = orient;
395 logfont.lfWeight = weight;
396 logfont.lfItalic = italic;
397 logfont.lfUnderline = underline;
398 logfont.lfStrikeOut = strikeout;
399 logfont.lfCharSet = charset;
400 logfont.lfOutPrecision = outpres;
401 logfont.lfClipPrecision = clippres;
402 logfont.lfQuality = quality;
403 logfont.lfPitchAndFamily = pitch;
405 if (name)
406 lstrcpynW(logfont.lfFaceName, name,
407 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
408 else
409 logfont.lfFaceName[0] = '\0';
411 return CreateFontIndirectW( &logfont );
415 /***********************************************************************
416 * FONT_SelectObject
418 * If the driver supports vector fonts we create a gdi font first and
419 * then call the driver to give it a chance to supply its own device
420 * font. If the driver wants to do this it returns TRUE and we can
421 * delete the gdi font, if the driver wants to use the gdi font it
422 * should return FALSE, to signal an error return GDI_ERROR. For
423 * drivers that don't support vector fonts they must supply their own
424 * font.
426 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
428 HGDIOBJ ret = 0;
429 DC *dc = DC_GetDCPtr( hdc );
431 if (!dc) return 0;
433 if (dc->hFont != handle || dc->gdiFont == NULL)
435 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
436 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
439 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
441 if (ret && dc->gdiFont) dc->gdiFont = 0;
443 if (ret == HGDI_ERROR)
444 ret = 0; /* SelectObject returns 0 on error */
445 else
447 ret = dc->hFont;
448 dc->hFont = handle;
450 GDI_ReleaseObj( hdc );
451 return ret;
455 /***********************************************************************
456 * FONT_GetObject16
458 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
460 FONTOBJ *font = obj;
461 LOGFONT16 lf16;
463 FONT_LogFontWTo16( &font->logfont, &lf16 );
465 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
466 memcpy( buffer, &lf16, count );
467 return count;
470 /***********************************************************************
471 * FONT_GetObjectA
473 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
475 FONTOBJ *font = obj;
476 LOGFONTA lfA;
478 FONT_LogFontWToA( &font->logfont, &lfA );
480 if (count > sizeof(lfA)) count = sizeof(lfA);
481 if(buffer)
482 memcpy( buffer, &lfA, count );
483 return count;
486 /***********************************************************************
487 * FONT_GetObjectW
489 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
491 FONTOBJ *font = obj;
492 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
493 if(buffer)
494 memcpy( buffer, &font->logfont, count );
495 return count;
499 /***********************************************************************
500 * FONT_DeleteObject
502 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
504 WineEngDestroyFontInstance( handle );
505 return GDI_FreeObject( handle, obj );
509 /***********************************************************************
510 * FONT_EnumInstance16
512 * Called by the device driver layer to pass font info
513 * down to the application.
515 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
516 DWORD fType, LPARAM lp )
518 fontEnum16 *pfe = (fontEnum16*)lp;
519 INT ret = 1;
520 DC *dc;
522 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
523 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
525 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
526 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
527 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
529 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
530 (UINT16)fType, (LPARAM)pfe->lpData );
531 /* get the lock again and make sure the DC is still valid */
532 dc = DC_GetDCPtr( pfe->hdc );
533 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
535 if (dc) GDI_ReleaseObj( pfe->hdc );
536 pfe->hdc = 0; /* make sure we don't try to release it later on */
537 ret = 0;
540 return ret;
543 /***********************************************************************
544 * FONT_EnumInstance
546 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, NEWTEXTMETRICEXW *ptm,
547 DWORD fType, LPARAM lp )
549 fontEnum32 *pfe = (fontEnum32*)lp;
550 INT ret = 1;
551 DC *dc;
553 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
554 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
555 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
557 /* convert font metrics */
558 ENUMLOGFONTEXA logfont;
559 NEWTEXTMETRICEXA tmA;
561 pfe->dwFlags |= ENUM_CALLED;
562 if (!(pfe->dwFlags & ENUM_UNICODE))
564 FONT_EnumLogFontExWToA( plf, &logfont);
565 FONT_NewTextMetricExWToA( ptm, &tmA );
566 plf = (LPENUMLOGFONTEXW)&logfont;
567 ptm = (NEWTEXTMETRICEXW *)&tmA;
569 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
571 ret = pfe->lpEnumFunc( &plf->elfLogFont, (TEXTMETRICW *)ptm, fType, pfe->lpData );
573 /* get the lock again and make sure the DC is still valid */
574 dc = DC_GetDCPtr( pfe->hdc );
575 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
577 if (dc) GDI_ReleaseObj( pfe->hdc );
578 pfe->hdc = 0; /* make sure we don't try to release it later on */
579 ret = 0;
582 return ret;
585 /***********************************************************************
586 * EnumFontFamiliesEx (GDI.613)
588 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
589 FONTENUMPROC16 efproc, LPARAM lParam,
590 DWORD dwFlags)
592 fontEnum16 fe16;
593 INT16 retVal = 0;
594 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
596 if (!dc) return 0;
597 fe16.hdc = HDC_32(hDC);
598 fe16.dc = dc;
599 fe16.physDev = dc->physDev;
601 if (dc->funcs->pEnumDeviceFonts)
603 NEWTEXTMETRICEX16 tm16;
604 ENUMLOGFONTEX16 lf16;
605 LOGFONTW lfW;
606 FONT_LogFont16ToW(plf, &lfW);
608 fe16.lpLogFontParam = plf;
609 fe16.lpEnumFunc = efproc;
610 fe16.lpData = lParam;
611 fe16.lpTextMetric = &tm16;
612 fe16.lpLogFont = &lf16;
613 fe16.segTextMetric = MapLS( &tm16 );
614 fe16.segLogFont = MapLS( &lf16 );
616 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
617 FONT_EnumInstance16, (LPARAM)&fe16 );
618 UnMapLS( fe16.segTextMetric );
619 UnMapLS( fe16.segLogFont );
621 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
622 return retVal;
625 /***********************************************************************
626 * FONT_EnumFontFamiliesEx
628 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
629 FONTENUMPROCW efproc,
630 LPARAM lParam, DWORD dwUnicode)
632 INT ret = 1, ret2;
633 DC *dc = DC_GetDCPtr( hDC );
634 fontEnum32 fe32;
635 BOOL enum_gdi_fonts;
637 if (!dc) return 0;
639 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
640 plf->lfCharSet);
641 fe32.lpLogFontParam = plf;
642 fe32.lpEnumFunc = efproc;
643 fe32.lpData = lParam;
644 fe32.dwFlags = dwUnicode;
645 fe32.hdc = hDC;
646 fe32.dc = dc;
647 fe32.physDev = dc->physDev;
649 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
651 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
653 ret = 0;
654 goto done;
657 if (enum_gdi_fonts)
658 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
659 fe32.dwFlags &= ~ENUM_CALLED;
660 if (ret && dc->funcs->pEnumDeviceFonts) {
661 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
662 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
663 ret = ret2;
665 done:
666 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
667 return ret;
670 /***********************************************************************
671 * EnumFontFamiliesExW (GDI32.@)
673 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
674 FONTENUMPROCW efproc,
675 LPARAM lParam, DWORD dwFlags )
677 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
680 /***********************************************************************
681 * EnumFontFamiliesExA (GDI32.@)
683 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
684 FONTENUMPROCA efproc,
685 LPARAM lParam, DWORD dwFlags)
687 LOGFONTW lfW;
688 FONT_LogFontAToW( plf, &lfW );
690 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
693 /***********************************************************************
694 * EnumFontFamilies (GDI.330)
696 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
697 FONTENUMPROC16 efproc, LPARAM lpData )
699 LOGFONT16 lf;
701 lf.lfCharSet = DEFAULT_CHARSET;
702 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
703 else lf.lfFaceName[0] = '\0';
705 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
708 /***********************************************************************
709 * EnumFontFamiliesA (GDI32.@)
711 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
712 FONTENUMPROCA efproc, LPARAM lpData )
714 LOGFONTA lf;
716 lf.lfCharSet = DEFAULT_CHARSET;
717 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
718 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
720 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
723 /***********************************************************************
724 * EnumFontFamiliesW (GDI32.@)
726 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
727 FONTENUMPROCW efproc, LPARAM lpData )
729 LOGFONTW lf;
731 lf.lfCharSet = DEFAULT_CHARSET;
732 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
733 else lf.lfFaceName[0] = 0;
735 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
738 /***********************************************************************
739 * EnumFonts (GDI.70)
741 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
742 LPARAM lpData )
744 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
747 /***********************************************************************
748 * EnumFontsA (GDI32.@)
750 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
751 LPARAM lpData )
753 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
756 /***********************************************************************
757 * EnumFontsW (GDI32.@)
759 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
760 LPARAM lpData )
762 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
766 /***********************************************************************
767 * GetTextCharacterExtra (GDI32.@)
769 INT WINAPI GetTextCharacterExtra( HDC hdc )
771 INT ret;
772 DC *dc = DC_GetDCPtr( hdc );
773 if (!dc) return 0x80000000;
774 ret = dc->charExtra;
775 GDI_ReleaseObj( hdc );
776 return ret;
780 /***********************************************************************
781 * SetTextCharacterExtra (GDI32.@)
783 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
785 INT prev;
786 DC * dc = DC_GetDCPtr( hdc );
787 if (!dc) return 0x80000000;
788 if (dc->funcs->pSetTextCharacterExtra)
789 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
790 else
792 prev = dc->charExtra;
793 dc->charExtra = extra;
795 GDI_ReleaseObj( hdc );
796 return prev;
800 /***********************************************************************
801 * SetTextJustification (GDI32.@)
803 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
805 BOOL ret = TRUE;
806 DC * dc = DC_GetDCPtr( hdc );
807 if (!dc) return FALSE;
808 if (dc->funcs->pSetTextJustification)
809 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
810 else
812 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
813 if (!extra) breaks = 0;
814 dc->breakTotalExtra = extra;
815 dc->breakCount = breaks;
816 if (breaks)
818 dc->breakExtra = extra / breaks;
819 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
821 else
823 dc->breakExtra = 0;
824 dc->breakRem = 0;
827 GDI_ReleaseObj( hdc );
828 return ret;
832 /***********************************************************************
833 * GetTextFaceA (GDI32.@)
835 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
837 INT res = GetTextFaceW(hdc, 0, NULL);
838 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
839 GetTextFaceW( hdc, res, nameW );
841 if (name)
842 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
843 NULL, NULL);
844 else
845 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
846 HeapFree( GetProcessHeap(), 0, nameW );
847 return res;
850 /***********************************************************************
851 * GetTextFaceW (GDI32.@)
853 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
855 FONTOBJ *font;
856 INT ret = 0;
858 DC * dc = DC_GetDCPtr( hdc );
859 if (!dc) return 0;
861 if(dc->gdiFont)
862 ret = WineEngGetTextFace(dc->gdiFont, count, name);
863 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
865 if (name)
867 lstrcpynW( name, font->logfont.lfFaceName, count );
868 ret = strlenW(name);
870 else ret = strlenW(font->logfont.lfFaceName) + 1;
871 GDI_ReleaseObj( dc->hFont );
873 GDI_ReleaseObj( hdc );
874 return ret;
878 /***********************************************************************
879 * GetTextExtentPoint32A (GDI32.@)
881 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
882 LPSIZE size )
884 BOOL ret = FALSE;
885 INT wlen;
886 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
888 if (p) {
889 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
890 HeapFree( GetProcessHeap(), 0, p );
893 TRACE("(%p %s %d %p): returning %ld x %ld\n",
894 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
895 return ret;
899 /***********************************************************************
900 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
902 * Computes width and height of the specified string.
904 * RETURNS
905 * Success: TRUE
906 * Failure: FALSE
908 BOOL WINAPI GetTextExtentPoint32W(
909 HDC hdc, /* [in] Handle of device context */
910 LPCWSTR str, /* [in] Address of text string */
911 INT count, /* [in] Number of characters in string */
912 LPSIZE size) /* [out] Address of structure for string size */
914 BOOL ret = FALSE;
915 DC * dc = DC_GetDCPtr( hdc );
916 if (!dc) return FALSE;
918 if(dc->gdiFont) {
919 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
920 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
921 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
923 else if(dc->funcs->pGetTextExtentPoint)
924 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
926 GDI_ReleaseObj( hdc );
928 TRACE("(%p %s %d %p): returning %ld x %ld\n",
929 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
930 return ret;
933 /***********************************************************************
934 * GetTextExtentPointI [GDI32.@]
936 * Computes width and height of the array of glyph indices.
938 * RETURNS
939 * Success: TRUE
940 * Failure: FALSE
942 BOOL WINAPI GetTextExtentPointI(
943 HDC hdc, /* [in] Handle of device context */
944 const WORD *indices, /* [in] Address of glyph index array */
945 INT count, /* [in] Number of glyphs in array */
946 LPSIZE size) /* [out] Address of structure for string size */
948 BOOL ret = FALSE;
949 DC * dc = DC_GetDCPtr( hdc );
950 if (!dc) return FALSE;
952 if(dc->gdiFont) {
953 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
954 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
955 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
957 else if(dc->funcs->pGetTextExtentPoint) {
958 FIXME("calling GetTextExtentPoint\n");
959 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
962 GDI_ReleaseObj( hdc );
964 TRACE("(%p %p %d %p): returning %ld x %ld\n",
965 hdc, indices, count, size, size->cx, size->cy );
966 return ret;
970 /***********************************************************************
971 * GetTextExtentPointA (GDI32.@)
973 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
974 LPSIZE size )
976 TRACE("not bug compatible.\n");
977 return GetTextExtentPoint32A( hdc, str, count, size );
980 /***********************************************************************
981 * GetTextExtentPointW (GDI32.@)
983 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
984 LPSIZE size )
986 TRACE("not bug compatible.\n");
987 return GetTextExtentPoint32W( hdc, str, count, size );
991 /***********************************************************************
992 * GetTextExtentExPointA (GDI32.@)
994 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
995 INT maxExt, LPINT lpnFit,
996 LPINT alpDx, LPSIZE size )
998 BOOL ret;
999 INT wlen;
1000 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1001 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1002 HeapFree( GetProcessHeap(), 0, p );
1003 return ret;
1007 /***********************************************************************
1008 * GetTextExtentExPointW (GDI32.@)
1010 * Return the size of the string as it would be if it was output properly by
1011 * e.g. TextOut.
1013 * This should include
1014 * - Intercharacter spacing
1015 * - justification spacing (not yet done)
1016 * - kerning? see below
1018 * Kerning. Since kerning would be carried out by the rendering code it should
1019 * be done by the driver. However they don't support it yet. Also I am not
1020 * yet persuaded that (certainly under Win95) any kerning is actually done.
1022 * str: According to MSDN this should be null-terminated. That is not true; a
1023 * null will not terminate it early.
1024 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1025 * than count. I have seen it be either the size of the full string or
1026 * 1 less than the size of the full string. I have not seen it bear any
1027 * resemblance to the portion that would fit.
1028 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1029 * trailing intercharacter spacing and any trailing justification.
1031 * FIXME
1032 * Currently we do this by measuring each character etc. We should do it by
1033 * passing the request to the driver, perhaps by extending the
1034 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1035 * thinking about kerning issues and rounding issues in the justification.
1038 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1039 INT maxExt, LPINT lpnFit,
1040 LPINT alpDx, LPSIZE size )
1042 int index, nFit, extent;
1043 SIZE tSize;
1044 BOOL ret = FALSE;
1046 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1048 size->cx = size->cy = nFit = extent = 0;
1049 for(index = 0; index < count; index++)
1051 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1052 /* GetTextExtentPoint includes intercharacter spacing. */
1053 /* FIXME - justification needs doing yet. Remember that the base
1054 * data will not be in logical coordinates.
1056 extent += tSize.cx;
1057 if( !lpnFit || extent <= maxExt )
1058 /* It is allowed to be equal. */
1060 nFit++;
1061 if( alpDx ) alpDx[index] = extent;
1063 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1064 str++;
1066 size->cx = extent;
1067 if(lpnFit) *lpnFit = nFit;
1068 ret = TRUE;
1070 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1072 done:
1073 return ret;
1076 /***********************************************************************
1077 * GetTextMetricsA (GDI32.@)
1079 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1081 TEXTMETRICW tm32;
1083 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1084 FONT_TextMetricWToA( &tm32, metrics );
1085 return TRUE;
1088 /***********************************************************************
1089 * GetTextMetricsW (GDI32.@)
1091 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1093 BOOL ret = FALSE;
1094 DC * dc = DC_GetDCPtr( hdc );
1095 if (!dc) return FALSE;
1097 if (dc->gdiFont)
1098 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1099 else if (dc->funcs->pGetTextMetrics)
1100 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1102 if (ret)
1104 /* device layer returns values in device units
1105 * therefore we have to convert them to logical */
1107 #define WDPTOLP(x) ((x<0)? \
1108 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1109 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1110 #define HDPTOLP(y) ((y<0)? \
1111 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1112 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1114 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1115 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1116 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1117 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1118 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1119 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1120 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1121 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1122 ret = TRUE;
1123 #undef WDPTOLP
1124 #undef HDPTOLP
1125 TRACE("text metrics:\n"
1126 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1127 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1128 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1129 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1130 " PitchAndFamily = %02x\n"
1131 " --------------------\n"
1132 " InternalLeading = %li\n"
1133 " Ascent = %li\n"
1134 " Descent = %li\n"
1135 " Height = %li\n",
1136 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1137 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1138 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1139 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1140 metrics->tmPitchAndFamily,
1141 metrics->tmInternalLeading,
1142 metrics->tmAscent,
1143 metrics->tmDescent,
1144 metrics->tmHeight );
1146 GDI_ReleaseObj( hdc );
1147 return ret;
1151 /***********************************************************************
1152 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1154 * NOTES
1155 * lpOTM should be LPOUTLINETEXTMETRIC
1157 * RETURNS
1158 * Success: Non-zero or size of required buffer
1159 * Failure: 0
1161 UINT16 WINAPI GetOutlineTextMetrics16(
1162 HDC16 hdc, /* [in] Handle of device context */
1163 UINT16 cbData, /* [in] Size of metric data array */
1164 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1166 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1167 return 0;
1171 /***********************************************************************
1172 * GetOutlineTextMetricsA (GDI32.@)
1173 * Gets metrics for TrueType fonts.
1176 * RETURNS
1177 * Success: Non-zero or size of required buffer
1178 * Failure: 0
1180 UINT WINAPI GetOutlineTextMetricsA(
1181 HDC hdc, /* [in] Handle of device context */
1182 UINT cbData, /* [in] Size of metric data array */
1183 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1185 char buf[512], *ptr;
1186 UINT ret, needed;
1187 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1188 INT left, len;
1190 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1191 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1192 return 0;
1193 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1194 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1197 needed = sizeof(OUTLINETEXTMETRICA);
1198 if(lpOTMW->otmpFamilyName)
1199 needed += WideCharToMultiByte(CP_ACP, 0,
1200 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1201 NULL, 0, NULL, NULL);
1202 if(lpOTMW->otmpFaceName)
1203 needed += WideCharToMultiByte(CP_ACP, 0,
1204 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1205 NULL, 0, NULL, NULL);
1206 if(lpOTMW->otmpStyleName)
1207 needed += WideCharToMultiByte(CP_ACP, 0,
1208 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1209 NULL, 0, NULL, NULL);
1210 if(lpOTMW->otmpFullName)
1211 needed += WideCharToMultiByte(CP_ACP, 0,
1212 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1213 NULL, 0, NULL, NULL);
1215 if(!lpOTM) {
1216 ret = needed;
1217 goto end;
1220 if(needed > cbData) {
1221 ret = 0;
1222 goto end;
1226 lpOTM->otmSize = needed;
1227 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1228 lpOTM->otmFiller = 0;
1229 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1230 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1231 lpOTM->otmfsType = lpOTMW->otmfsType;
1232 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1233 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1234 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1235 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1236 lpOTM->otmAscent = lpOTMW->otmAscent;
1237 lpOTM->otmDescent = lpOTMW->otmDescent;
1238 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1239 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1240 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1241 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1242 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1243 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1244 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1245 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1246 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1247 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1248 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1249 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1250 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1251 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1252 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1253 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1256 ptr = (char*)(lpOTM + 1);
1257 left = needed - sizeof(*lpOTM);
1259 if(lpOTMW->otmpFamilyName) {
1260 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1261 len = WideCharToMultiByte(CP_ACP, 0,
1262 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1263 ptr, left, NULL, NULL);
1264 left -= len;
1265 ptr += len;
1266 } else
1267 lpOTM->otmpFamilyName = 0;
1269 if(lpOTMW->otmpFaceName) {
1270 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1271 len = WideCharToMultiByte(CP_ACP, 0,
1272 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1273 ptr, left, NULL, NULL);
1274 left -= len;
1275 ptr += len;
1276 } else
1277 lpOTM->otmpFaceName = 0;
1279 if(lpOTMW->otmpStyleName) {
1280 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1281 len = WideCharToMultiByte(CP_ACP, 0,
1282 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1283 ptr, left, NULL, NULL);
1284 left -= len;
1285 ptr += len;
1286 } else
1287 lpOTM->otmpStyleName = 0;
1289 if(lpOTMW->otmpFullName) {
1290 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1291 len = WideCharToMultiByte(CP_ACP, 0,
1292 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1293 ptr, left, NULL, NULL);
1294 left -= len;
1295 } else
1296 lpOTM->otmpFullName = 0;
1298 assert(left == 0);
1300 ret = needed;
1302 end:
1303 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1304 HeapFree(GetProcessHeap(), 0, lpOTMW);
1306 return ret;
1310 /***********************************************************************
1311 * GetOutlineTextMetricsW [GDI32.@]
1313 UINT WINAPI GetOutlineTextMetricsW(
1314 HDC hdc, /* [in] Handle of device context */
1315 UINT cbData, /* [in] Size of metric data array */
1316 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1318 DC *dc = DC_GetDCPtr( hdc );
1319 UINT ret;
1321 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1322 if(!dc) return 0;
1324 if(dc->gdiFont) {
1325 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1326 if(ret && ret <= cbData) {
1327 #define WDPTOLP(x) ((x<0)? \
1328 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1329 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1330 #define HDPTOLP(y) ((y<0)? \
1331 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1332 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1334 lpOTM->otmTextMetrics.tmHeight = HDPTOLP(lpOTM->otmTextMetrics.tmHeight);
1335 lpOTM->otmTextMetrics.tmAscent = HDPTOLP(lpOTM->otmTextMetrics.tmAscent);
1336 lpOTM->otmTextMetrics.tmDescent = HDPTOLP(lpOTM->otmTextMetrics.tmDescent);
1337 lpOTM->otmTextMetrics.tmInternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmInternalLeading);
1338 lpOTM->otmTextMetrics.tmExternalLeading = HDPTOLP(lpOTM->otmTextMetrics.tmExternalLeading);
1339 lpOTM->otmTextMetrics.tmAveCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmAveCharWidth);
1340 lpOTM->otmTextMetrics.tmMaxCharWidth = WDPTOLP(lpOTM->otmTextMetrics.tmMaxCharWidth);
1341 lpOTM->otmTextMetrics.tmOverhang = WDPTOLP(lpOTM->otmTextMetrics.tmOverhang);
1342 lpOTM->otmAscent = HDPTOLP(lpOTM->otmAscent);
1343 lpOTM->otmDescent = HDPTOLP(lpOTM->otmDescent);
1344 lpOTM->otmLineGap = HDPTOLP(lpOTM->otmLineGap);
1345 lpOTM->otmsCapEmHeight = HDPTOLP(lpOTM->otmsCapEmHeight);
1346 lpOTM->otmsXHeight = HDPTOLP(lpOTM->otmsXHeight);
1347 lpOTM->otmrcFontBox.top = HDPTOLP(lpOTM->otmrcFontBox.top);
1348 lpOTM->otmrcFontBox.bottom = HDPTOLP(lpOTM->otmrcFontBox.bottom);
1349 lpOTM->otmrcFontBox.left = WDPTOLP(lpOTM->otmrcFontBox.left);
1350 lpOTM->otmrcFontBox.right = WDPTOLP(lpOTM->otmrcFontBox.right);
1351 lpOTM->otmMacAscent = HDPTOLP(lpOTM->otmMacAscent);
1352 lpOTM->otmMacDescent = HDPTOLP(lpOTM->otmMacDescent);
1353 lpOTM->otmMacLineGap = HDPTOLP(lpOTM->otmMacLineGap);
1354 lpOTM->otmptSubscriptSize.x = WDPTOLP(lpOTM->otmptSubscriptSize.x);
1355 lpOTM->otmptSubscriptSize.y = HDPTOLP(lpOTM->otmptSubscriptSize.y);
1356 lpOTM->otmptSubscriptOffset.x = WDPTOLP(lpOTM->otmptSubscriptOffset.x);
1357 lpOTM->otmptSubscriptOffset.y = HDPTOLP(lpOTM->otmptSubscriptOffset.y);
1358 lpOTM->otmptSuperscriptSize.x = WDPTOLP(lpOTM->otmptSuperscriptSize.x);
1359 lpOTM->otmptSuperscriptSize.y = HDPTOLP(lpOTM->otmptSuperscriptSize.y);
1360 lpOTM->otmptSuperscriptOffset.x = WDPTOLP(lpOTM->otmptSuperscriptOffset.x);
1361 lpOTM->otmptSuperscriptOffset.y = HDPTOLP(lpOTM->otmptSuperscriptOffset.y);
1362 lpOTM->otmsStrikeoutSize = HDPTOLP(lpOTM->otmsStrikeoutSize);
1363 lpOTM->otmsStrikeoutPosition = HDPTOLP(lpOTM->otmsStrikeoutPosition);
1364 lpOTM->otmsUnderscoreSize = HDPTOLP(lpOTM->otmsUnderscoreSize);
1365 lpOTM->otmsUnderscorePosition = HDPTOLP(lpOTM->otmsUnderscorePosition);
1366 #undef WDPTOLP
1367 #undef HDPTOLP
1371 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1372 but really this should just be a return 0. */
1374 ret = sizeof(*lpOTM);
1375 if (lpOTM) {
1376 if(cbData < ret)
1377 ret = 0;
1378 else {
1379 memset(lpOTM, 0, ret);
1380 lpOTM->otmSize = sizeof(*lpOTM);
1381 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1383 Further fill of the structure not implemented,
1384 Needs real values for the structure members
1389 GDI_ReleaseObj(hdc);
1390 return ret;
1394 /***********************************************************************
1395 * GetCharWidthW (GDI32.@)
1396 * GetCharWidth32W (GDI32.@)
1398 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1399 LPINT buffer )
1401 UINT i, extra;
1402 BOOL ret = FALSE;
1403 DC * dc = DC_GetDCPtr( hdc );
1404 if (!dc) return FALSE;
1406 if (dc->gdiFont)
1407 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1408 else if (dc->funcs->pGetCharWidth)
1409 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1411 if (ret)
1413 /* convert device units to logical */
1415 extra = dc->vportExtX >> 1;
1416 for( i = firstChar; i <= lastChar; i++, buffer++ )
1417 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1418 ret = TRUE;
1420 GDI_ReleaseObj( hdc );
1421 return ret;
1425 /***********************************************************************
1426 * GetCharWidthA (GDI32.@)
1427 * GetCharWidth32A (GDI32.@)
1429 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1430 LPINT buffer )
1432 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1433 LPSTR str;
1434 LPWSTR wstr;
1435 BOOL ret = TRUE;
1437 if(count <= 0) return FALSE;
1439 str = HeapAlloc(GetProcessHeap(), 0, count);
1440 for(i = 0; i < count; i++)
1441 str[i] = (BYTE)(firstChar + i);
1443 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1445 for(i = 0; i < wlen; i++)
1447 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1449 ret = FALSE;
1450 break;
1452 buffer++;
1455 HeapFree(GetProcessHeap(), 0, str);
1456 HeapFree(GetProcessHeap(), 0, wstr);
1458 return ret;
1462 /* FIXME: all following APIs ******************************************/
1465 /***********************************************************************
1466 * SetMapperFlags (GDI32.@)
1468 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1470 DC *dc = DC_GetDCPtr( hDC );
1471 DWORD ret = 0;
1472 if(!dc) return 0;
1473 if(dc->funcs->pSetMapperFlags)
1474 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1475 else
1476 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1477 GDI_ReleaseObj( hDC );
1478 return ret;
1481 /***********************************************************************
1482 * GetAspectRatioFilterEx (GDI.486)
1484 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1486 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1487 return FALSE;
1490 /***********************************************************************
1491 * GetAspectRatioFilterEx (GDI32.@)
1493 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1495 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1496 return FALSE;
1500 /***********************************************************************
1501 * GetCharABCWidthsA (GDI32.@)
1503 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1504 LPABC abc )
1506 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1507 LPSTR str;
1508 LPWSTR wstr;
1509 BOOL ret = TRUE;
1511 if(count <= 0) return FALSE;
1513 str = HeapAlloc(GetProcessHeap(), 0, count);
1514 for(i = 0; i < count; i++)
1515 str[i] = (BYTE)(firstChar + i);
1517 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1519 for(i = 0; i < wlen; i++)
1521 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1523 ret = FALSE;
1524 break;
1526 abc++;
1529 HeapFree(GetProcessHeap(), 0, str);
1530 HeapFree(GetProcessHeap(), 0, wstr);
1532 return ret;
1536 /******************************************************************************
1537 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1539 * PARAMS
1540 * hdc [I] Handle of device context
1541 * firstChar [I] First character in range to query
1542 * lastChar [I] Last character in range to query
1543 * abc [O] Address of character-width structure
1545 * NOTES
1546 * Only works with TrueType fonts
1548 * RETURNS
1549 * Success: TRUE
1550 * Failure: FALSE
1552 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1553 LPABC abc )
1555 DC *dc = DC_GetDCPtr(hdc);
1556 int i;
1557 GLYPHMETRICS gm;
1558 BOOL ret = FALSE;
1560 if(dc->gdiFont) {
1561 for (i=firstChar;i<=lastChar;i++) {
1562 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1563 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1564 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1565 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1567 ret = TRUE;
1569 GDI_ReleaseObj(hdc);
1570 return ret;
1574 /***********************************************************************
1575 * GetGlyphOutline (GDI.309)
1577 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1578 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1579 LPVOID lpBuffer, const MAT2 *lpmat2 )
1581 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1582 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1583 return (DWORD)-1; /* failure */
1587 /***********************************************************************
1588 * GetGlyphOutlineA (GDI32.@)
1590 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1591 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1592 LPVOID lpBuffer, const MAT2 *lpmat2 )
1594 LPWSTR p = NULL;
1595 DWORD ret;
1596 UINT c;
1598 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1599 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1600 c = p[0];
1601 } else
1602 c = uChar;
1603 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1604 lpmat2);
1605 if(p)
1606 HeapFree(GetProcessHeap(), 0, p);
1607 return ret;
1610 /***********************************************************************
1611 * GetGlyphOutlineW (GDI32.@)
1613 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1614 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1615 LPVOID lpBuffer, const MAT2 *lpmat2 )
1617 DC *dc = DC_GetDCPtr(hdc);
1618 DWORD ret;
1620 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1621 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1623 if(!dc) return GDI_ERROR;
1625 if(dc->gdiFont)
1626 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1627 cbBuffer, lpBuffer, lpmat2);
1628 else
1629 ret = GDI_ERROR;
1631 GDI_ReleaseObj(hdc);
1632 return ret;
1636 /***********************************************************************
1637 * CreateScalableFontResourceA (GDI32.@)
1639 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1640 LPCSTR lpszResourceFile,
1641 LPCSTR lpszFontFile,
1642 LPCSTR lpszCurrentPath )
1644 HANDLE f;
1646 /* fHidden=1 - only visible for the calling app, read-only, not
1647 * enumbered with EnumFonts/EnumFontFamilies
1648 * lpszCurrentPath can be NULL
1650 FIXME("(%ld,%s,%s,%s): stub\n",
1651 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1652 debugstr_a(lpszCurrentPath) );
1654 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1655 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1656 CloseHandle(f);
1657 SetLastError(ERROR_FILE_EXISTS);
1658 return FALSE;
1660 return FALSE; /* create failed */
1663 /***********************************************************************
1664 * CreateScalableFontResourceW (GDI32.@)
1666 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1667 LPCWSTR lpszResourceFile,
1668 LPCWSTR lpszFontFile,
1669 LPCWSTR lpszCurrentPath )
1671 FIXME("(%ld,%p,%p,%p): stub\n",
1672 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1673 return FALSE; /* create failed */
1677 /*************************************************************************
1678 * GetRasterizerCaps (GDI32.@)
1680 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1682 lprs->nSize = sizeof(RASTERIZER_STATUS);
1683 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1684 lprs->nLanguageID = 0;
1685 return TRUE;
1689 /*************************************************************************
1690 * GetKerningPairsA (GDI32.@)
1692 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs, LPKERNINGPAIR lpKerningPairs )
1694 int i;
1695 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1696 for (i = 0; i < cPairs; i++)
1697 lpKerningPairs[i].iKernAmount = 0;
1698 return 0;
1702 /*************************************************************************
1703 * GetKerningPairsW (GDI32.@)
1705 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1706 LPKERNINGPAIR lpKerningPairs )
1708 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1711 /*************************************************************************
1712 * TranslateCharsetInfo [GDI32.@]
1714 * Fills a CHARSETINFO structure for a character set, code page, or
1715 * font. This allows making the correspondance between different labelings
1716 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1717 * of the same encoding.
1719 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1720 * only one codepage should be set in *lpSrc.
1722 * RETURNS
1723 * TRUE on success, FALSE on failure.
1726 BOOL WINAPI TranslateCharsetInfo(
1727 LPDWORD lpSrc, /* [in]
1728 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1729 if flags == TCI_SRCCHARSET: a character set value
1730 if flags == TCI_SRCCODEPAGE: a code page value
1732 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1733 DWORD flags /* [in] determines interpretation of lpSrc */
1735 int index = 0;
1736 switch (flags) {
1737 case TCI_SRCFONTSIG:
1738 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1739 break;
1740 case TCI_SRCCODEPAGE:
1741 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1742 break;
1743 case TCI_SRCCHARSET:
1744 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1745 break;
1746 default:
1747 return FALSE;
1749 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1750 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1751 return TRUE;
1754 /*************************************************************************
1755 * GetFontLanguageInfo (GDI32.@)
1757 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
1759 FONTSIGNATURE fontsig;
1760 static const DWORD GCP_DBCS_MASK=0x003F0000,
1761 GCP_DIACRITIC_MASK=0x00000000,
1762 FLI_GLYPHS_MASK=0x00000000,
1763 GCP_GLYPHSHAPE_MASK=0x00000040,
1764 GCP_KASHIDA_MASK=0x00000000,
1765 GCP_LIGATE_MASK=0x00000000,
1766 GCP_USEKERNING_MASK=0x00000000,
1767 GCP_REORDER_MASK=0x00000060;
1769 DWORD result=0;
1771 GetTextCharsetInfo( hdc, &fontsig, 0 );
1772 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1774 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
1775 result|=GCP_DBCS;
1777 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
1778 result|=GCP_DIACRITIC;
1780 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
1781 result|=FLI_GLYPHS;
1783 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
1784 result|=GCP_GLYPHSHAPE;
1786 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
1787 result|=GCP_KASHIDA;
1789 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
1790 result|=GCP_LIGATE;
1792 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
1793 result|=GCP_USEKERNING;
1795 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
1796 result|=GCP_REORDER;
1798 return result;
1802 /*************************************************************************
1803 * GetFontData [GDI32.@] Retrieve data for TrueType font
1805 * RETURNS
1807 * success: Number of bytes returned
1808 * failure: GDI_ERROR
1810 * NOTES
1812 * Calls SetLastError()
1815 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1816 LPVOID buffer, DWORD length)
1818 DC *dc = DC_GetDCPtr(hdc);
1819 DWORD ret = GDI_ERROR;
1821 if(!dc) return GDI_ERROR;
1823 if(dc->gdiFont)
1824 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1826 GDI_ReleaseObj(hdc);
1827 return ret;
1830 /*************************************************************************
1831 * GetGlyphIndicesA [GDI32.@]
1833 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
1834 LPWORD pgi, DWORD flags)
1836 DWORD ret;
1837 WCHAR *lpstrW;
1838 INT countW;
1840 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1841 hdc, debugstr_an(lpstr, count), count, pgi, flags);
1843 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
1844 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
1845 HeapFree(GetProcessHeap(), 0, lpstrW);
1847 return ret;
1850 /*************************************************************************
1851 * GetGlyphIndicesW [GDI32.@]
1853 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
1854 LPWORD pgi, DWORD flags)
1856 DC *dc = DC_GetDCPtr(hdc);
1857 DWORD ret = GDI_ERROR;
1859 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1860 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
1862 if(!dc) return GDI_ERROR;
1864 if(dc->gdiFont)
1865 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
1867 GDI_ReleaseObj(hdc);
1868 return ret;
1871 /*************************************************************************
1872 * GetCharacterPlacementA [GDI32.@]
1874 * NOTES:
1875 * the web browser control of ie4 calls this with dwFlags=0
1877 DWORD WINAPI
1878 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1879 INT nMaxExtent, GCP_RESULTSA *lpResults,
1880 DWORD dwFlags)
1882 WCHAR *lpStringW;
1883 INT uCountW, i;
1884 GCP_RESULTSW resultsW;
1885 DWORD ret;
1886 UINT font_cp;
1888 TRACE("%s, %d, %d, 0x%08lx\n",
1889 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
1891 /* both structs are equal in size */
1892 memcpy(&resultsW, lpResults, sizeof(resultsW));
1894 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
1895 if(lpResults->lpOutString)
1896 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
1898 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
1900 if(lpResults->lpOutString) {
1901 if(font_cp != CP_SYMBOL)
1902 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
1903 lpResults->lpOutString, uCount, NULL, NULL );
1904 else
1905 for(i = 0; i < uCount; i++)
1906 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
1909 HeapFree(GetProcessHeap(), 0, lpStringW);
1910 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
1912 return ret;
1915 /*************************************************************************
1916 * GetCharacterPlacementW [GDI32.@]
1918 * Retrieve information about a string. This includes the width, reordering,
1919 * Glyphing and so on.
1921 * RETURNS
1923 * The width and height of the string if succesful, 0 if failed.
1925 * BUGS
1927 * All flags except GCP_REORDER are not yet implemented.
1928 * Reordering is not 100% complient to the Windows BiDi method.
1929 * Caret positioning is not yet implemented.
1930 * Classes are not yet implemented.
1933 DWORD WINAPI
1934 GetCharacterPlacementW(
1935 HDC hdc, /* [in] Device context for which the rendering is to be done */
1936 LPCWSTR lpString, /* [in] The string for which information is to be returned */
1937 INT uCount, /* [in] Number of WORDS in string. */
1938 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
1939 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
1940 DWORD dwFlags /* [in] Flags specifying how to process the string */
1943 DWORD ret=0;
1944 SIZE size;
1945 UINT i, nSet;
1947 TRACE("%s, %d, %d, 0x%08lx\n",
1948 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
1950 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
1951 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
1952 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
1953 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
1954 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
1956 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
1957 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1958 if(lpResults->lpClass) FIXME("classes not implemented\n");
1960 nSet = (UINT)uCount;
1961 if(nSet > lpResults->nGlyphs)
1962 nSet = lpResults->nGlyphs;
1964 /* return number of initialized fields */
1965 lpResults->nGlyphs = nSet;
1967 if(dwFlags==0)
1969 /* Treat the case where no special handling was requested in a fastpath way */
1970 /* copy will do if the GCP_REORDER flag is not set */
1971 if(lpResults->lpOutString)
1972 for(i=0; i<nSet && lpString[i]!=0; ++i )
1973 lpResults->lpOutString[i]=lpString[i];
1975 if(lpResults->lpOrder)
1977 for(i = 0; i < nSet; i++)
1978 lpResults->lpOrder[i] = i;
1982 if((dwFlags&GCP_REORDER)!=0)
1984 WORD *pwCharType;
1985 int run_end;
1986 /* Keep a static table that translates the C2 types to something meaningful */
1987 /* 1 - left to right
1988 * -1 - right to left
1989 * 0 - neutral
1991 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
1993 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
1994 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
1996 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1998 return 0;
2001 /* Fill in the order array with directionality values */
2002 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2004 /* The complete and correct (at least according to MS) BiDi algorythm is not
2005 * yet implemented here. Instead, we just make sure that consecutive runs of
2006 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
2007 * that are between runs of opposing directions the base (ok, always LTR) dir.
2008 * While this is a LONG way from a BiDi algorithm, it does produce more or less
2009 * readable results.
2011 for( i=0; i<uCount; i+=run_end )
2013 for( run_end=1; i+run_end<uCount &&
2014 (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2015 chardir[pwCharType[i+run_end]]==0); ++run_end )
2018 if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2020 /* A LTR run */
2021 if(lpResults->lpOutString)
2023 int j;
2024 for( j=0; j<run_end; j++ )
2026 lpResults->lpOutString[i+j]=lpString[i+j];
2030 if(lpResults->lpOrder)
2032 int j;
2033 for( j=0; j<run_end; j++ )
2034 lpResults->lpOrder[i+j] = i+j;
2036 } else
2038 /* A RTL run */
2040 /* Since, at this stage, the paragraph context is always LTR,
2041 * remove any neutrals from the end of this run.
2043 if( chardir[pwCharType[i]]!=0 )
2044 while( chardir[pwCharType[i+run_end-1]]==0 )
2045 --run_end;
2047 if(lpResults->lpOutString)
2049 int j;
2050 for( j=0; j<run_end; j++ )
2052 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2056 if(lpResults->lpOrder)
2058 int j;
2059 for( j=0; j<run_end; j++ )
2060 lpResults->lpOrder[i+j] = i+run_end-j-1;
2065 HeapFree(GetProcessHeap(), 0, pwCharType);
2068 /* FIXME: Will use the placement chars */
2069 if (lpResults->lpDx)
2071 int c;
2072 for (i = 0; i < nSet; i++)
2074 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2075 lpResults->lpDx[i]= c;
2079 if(lpResults->lpGlyphs)
2080 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2082 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2083 ret = MAKELONG(size.cx, size.cy);
2085 return ret;
2088 /*************************************************************************
2089 * GetCharABCWidthsFloatA [GDI32.@]
2091 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2092 LPABCFLOAT lpABCF)
2094 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2095 return 0;
2098 /*************************************************************************
2099 * GetCharABCWidthsFloatW [GDI32.@]
2101 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2102 UINT iLastChar, LPABCFLOAT lpABCF)
2104 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2105 return 0;
2108 /*************************************************************************
2109 * GetCharWidthFloatA [GDI32.@]
2111 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2112 UINT iLastChar, PFLOAT pxBuffer)
2114 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2115 return 0;
2118 /*************************************************************************
2119 * GetCharWidthFloatW [GDI32.@]
2121 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2122 UINT iLastChar, PFLOAT pxBuffer)
2124 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2125 return 0;
2129 /***********************************************************************
2131 * Font Resource API *
2133 ***********************************************************************/
2135 /***********************************************************************
2136 * AddFontResourceA (GDI32.@)
2138 INT WINAPI AddFontResourceA( LPCSTR str )
2140 return AddFontResourceExA( str, 0, NULL);
2143 /***********************************************************************
2144 * AddFontResourceW (GDI32.@)
2146 INT WINAPI AddFontResourceW( LPCWSTR str )
2148 return AddFontResourceExW(str, 0, NULL);
2152 /***********************************************************************
2153 * AddFontResourceExA (GDI32.@)
2155 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2157 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2158 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2159 INT ret;
2161 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2162 ret = AddFontResourceExW(strW, fl, pdv);
2163 HeapFree(GetProcessHeap(), 0, strW);
2164 return ret;
2167 /***********************************************************************
2168 * AddFontResourceExW (GDI32.@)
2170 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2172 return WineEngAddFontResourceEx(str, fl, pdv);
2175 /***********************************************************************
2176 * RemoveFontResourceA (GDI32.@)
2178 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2180 return RemoveFontResourceExA(str, 0, 0);
2183 /***********************************************************************
2184 * RemoveFontResourceW (GDI32.@)
2186 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2188 return RemoveFontResourceExW(str, 0, 0);
2191 /***********************************************************************
2192 * RemoveFontResourceExA (GDI32.@)
2194 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2196 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2197 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2198 INT ret;
2200 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2201 ret = RemoveFontResourceExW(strW, fl, pdv);
2202 HeapFree(GetProcessHeap(), 0, strW);
2203 return ret;
2206 /***********************************************************************
2207 * RemoveFontResourceExW (GDI32.@)
2209 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2211 return WineEngRemoveFontResourceEx(str, fl, pdv);