4 * Copyright 1993 Alexandre Julliard
6 * Copyright 2002,2003 Shachar Shemesh
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "wine/port.h"
36 #include "gdi_private.h"
37 #include "wine/unicode.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(font);
41 WINE_DECLARE_DEBUG_CHANNEL(gdi);
43 /* Device -> World size conversion */
45 /* Performs a device to world transformation on the specified width (which
46 * is in integer format).
48 static inline INT INTERNAL_XDSTOWS(DC *dc, INT width)
52 /* Perform operation with floating point */
53 floatWidth = (FLOAT)width * dc->xformVport2World.eM11;
54 /* Round to integers */
55 return GDI_ROUND(floatWidth);
58 /* Performs a device to world transformation on the specified size (which
59 * is in integer format).
61 static inline INT INTERNAL_YDSTOWS(DC *dc, INT height)
65 /* Perform operation with floating point */
66 floatHeight = (FLOAT)height * dc->xformVport2World.eM22;
67 /* Round to integers */
68 return GDI_ROUND(floatHeight);
72 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
73 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
74 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
75 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
76 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
78 static const struct gdi_obj_funcs font_funcs =
80 FONT_SelectObject, /* pSelectObject */
81 FONT_GetObject16, /* pGetObject16 */
82 FONT_GetObjectA, /* pGetObjectA */
83 FONT_GetObjectW, /* pGetObjectW */
84 NULL, /* pUnrealizeObject */
85 FONT_DeleteObject /* pDeleteObject */
88 #define ENUM_UNICODE 0x00000001
89 #define ENUM_CALLED 0x00000002
99 LPLOGFONT16 lpLogFontParam;
100 FONTENUMPROC16 lpEnumFunc;
103 LPNEWTEXTMETRICEX16 lpTextMetric;
104 LPENUMLOGFONTEX16 lpLogFont;
105 SEGPTR segTextMetric;
115 LPLOGFONTW lpLogFontParam;
116 FONTENUMPROCW lpEnumFunc;
125 * For TranslateCharsetInfo
127 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
128 #define MAXTCIINDEX 32
129 static const CHARSETINFO FONT_tci[MAXTCIINDEX] = {
131 { ANSI_CHARSET, 1252, FS(0)},
132 { EASTEUROPE_CHARSET, 1250, FS(1)},
133 { RUSSIAN_CHARSET, 1251, FS(2)},
134 { GREEK_CHARSET, 1253, FS(3)},
135 { TURKISH_CHARSET, 1254, FS(4)},
136 { HEBREW_CHARSET, 1255, FS(5)},
137 { ARABIC_CHARSET, 1256, FS(6)},
138 { BALTIC_CHARSET, 1257, FS(7)},
139 { VIETNAMESE_CHARSET, 1258, FS(8)},
140 /* reserved by ANSI */
141 { DEFAULT_CHARSET, 0, FS(0)},
142 { DEFAULT_CHARSET, 0, FS(0)},
143 { DEFAULT_CHARSET, 0, FS(0)},
144 { DEFAULT_CHARSET, 0, FS(0)},
145 { DEFAULT_CHARSET, 0, FS(0)},
146 { DEFAULT_CHARSET, 0, FS(0)},
147 { DEFAULT_CHARSET, 0, FS(0)},
149 { THAI_CHARSET, 874, FS(16)},
150 { SHIFTJIS_CHARSET, 932, FS(17)},
151 { GB2312_CHARSET, 936, FS(18)},
152 { HANGEUL_CHARSET, 949, FS(19)},
153 { CHINESEBIG5_CHARSET, 950, FS(20)},
154 { JOHAB_CHARSET, 1361, FS(21)},
155 /* reserved for alternate ANSI and OEM */
156 { DEFAULT_CHARSET, 0, FS(0)},
157 { DEFAULT_CHARSET, 0, FS(0)},
158 { DEFAULT_CHARSET, 0, FS(0)},
159 { DEFAULT_CHARSET, 0, FS(0)},
160 { DEFAULT_CHARSET, 0, FS(0)},
161 { DEFAULT_CHARSET, 0, FS(0)},
162 { DEFAULT_CHARSET, 0, FS(0)},
163 { DEFAULT_CHARSET, 0, FS(0)},
164 /* reserved for system */
165 { DEFAULT_CHARSET, 0, FS(0)},
166 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
169 /***********************************************************************
170 * LOGFONT conversion functions.
172 static void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
174 font16->lfHeight = font32->lfHeight;
175 font16->lfWidth = font32->lfWidth;
176 font16->lfEscapement = font32->lfEscapement;
177 font16->lfOrientation = font32->lfOrientation;
178 font16->lfWeight = font32->lfWeight;
179 font16->lfItalic = font32->lfItalic;
180 font16->lfUnderline = font32->lfUnderline;
181 font16->lfStrikeOut = font32->lfStrikeOut;
182 font16->lfCharSet = font32->lfCharSet;
183 font16->lfOutPrecision = font32->lfOutPrecision;
184 font16->lfClipPrecision = font32->lfClipPrecision;
185 font16->lfQuality = font32->lfQuality;
186 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
187 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
188 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
189 font16->lfFaceName[LF_FACESIZE-1] = 0;
192 static void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
194 font32->lfHeight = font16->lfHeight;
195 font32->lfWidth = font16->lfWidth;
196 font32->lfEscapement = font16->lfEscapement;
197 font32->lfOrientation = font16->lfOrientation;
198 font32->lfWeight = font16->lfWeight;
199 font32->lfItalic = font16->lfItalic;
200 font32->lfUnderline = font16->lfUnderline;
201 font32->lfStrikeOut = font16->lfStrikeOut;
202 font32->lfCharSet = font16->lfCharSet;
203 font32->lfOutPrecision = font16->lfOutPrecision;
204 font32->lfClipPrecision = font16->lfClipPrecision;
205 font32->lfQuality = font16->lfQuality;
206 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
207 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
208 font32->lfFaceName[LF_FACESIZE-1] = 0;
211 static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
213 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
214 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
216 fontW->lfFaceName[LF_FACESIZE-1] = 0;
219 static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
221 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
222 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
223 LF_FACESIZE, NULL, NULL);
224 fontA->lfFaceName[LF_FACESIZE-1] = 0;
227 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
229 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
231 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
232 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
233 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
234 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
235 font16->elfStyle, LF_FACESIZE, NULL, NULL );
236 font16->elfStyle[LF_FACESIZE-1] = '\0';
237 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
238 font16->elfScript, LF_FACESIZE, NULL, NULL );
239 font16->elfScript[LF_FACESIZE-1] = '\0';
242 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
244 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
246 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
247 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
248 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
249 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
250 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
251 fontA->elfStyle[LF_FACESIZE-1] = '\0';
252 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
253 fontA->elfScript, LF_FACESIZE, NULL, NULL );
254 fontA->elfScript[LF_FACESIZE-1] = '\0';
257 /***********************************************************************
258 * TEXTMETRIC conversion functions.
260 static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
262 ptmA->tmHeight = ptmW->tmHeight;
263 ptmA->tmAscent = ptmW->tmAscent;
264 ptmA->tmDescent = ptmW->tmDescent;
265 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
266 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
267 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
268 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
269 ptmA->tmWeight = ptmW->tmWeight;
270 ptmA->tmOverhang = ptmW->tmOverhang;
271 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
272 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
273 ptmA->tmFirstChar = ptmW->tmFirstChar > 255 ? 255 : ptmW->tmFirstChar;
274 ptmA->tmLastChar = ptmW->tmLastChar > 255 ? 255 : ptmW->tmLastChar;
275 ptmA->tmDefaultChar = ptmW->tmDefaultChar > 255 ? 255 : ptmW->tmDefaultChar;
276 ptmA->tmBreakChar = ptmW->tmBreakChar > 255 ? 255 : ptmW->tmBreakChar;
277 ptmA->tmItalic = ptmW->tmItalic;
278 ptmA->tmUnderlined = ptmW->tmUnderlined;
279 ptmA->tmStruckOut = ptmW->tmStruckOut;
280 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
281 ptmA->tmCharSet = ptmW->tmCharSet;
285 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
287 ptm16->ntmTm.tmHeight = ptmW->ntmTm.tmHeight;
288 ptm16->ntmTm.tmAscent = ptmW->ntmTm.tmAscent;
289 ptm16->ntmTm.tmDescent = ptmW->ntmTm.tmDescent;
290 ptm16->ntmTm.tmInternalLeading = ptmW->ntmTm.tmInternalLeading;
291 ptm16->ntmTm.tmExternalLeading = ptmW->ntmTm.tmExternalLeading;
292 ptm16->ntmTm.tmAveCharWidth = ptmW->ntmTm.tmAveCharWidth;
293 ptm16->ntmTm.tmMaxCharWidth = ptmW->ntmTm.tmMaxCharWidth;
294 ptm16->ntmTm.tmWeight = ptmW->ntmTm.tmWeight;
295 ptm16->ntmTm.tmOverhang = ptmW->ntmTm.tmOverhang;
296 ptm16->ntmTm.tmDigitizedAspectX = ptmW->ntmTm.tmDigitizedAspectX;
297 ptm16->ntmTm.tmDigitizedAspectY = ptmW->ntmTm.tmDigitizedAspectY;
298 ptm16->ntmTm.tmFirstChar = ptmW->ntmTm.tmFirstChar > 255 ? 255 : ptmW->ntmTm.tmFirstChar;
299 ptm16->ntmTm.tmLastChar = ptmW->ntmTm.tmLastChar > 255 ? 255 : ptmW->ntmTm.tmLastChar;
300 ptm16->ntmTm.tmDefaultChar = ptmW->ntmTm.tmDefaultChar > 255 ? 255 : ptmW->ntmTm.tmDefaultChar;
301 ptm16->ntmTm.tmBreakChar = ptmW->ntmTm.tmBreakChar > 255 ? 255 : ptmW->ntmTm.tmBreakChar;
302 ptm16->ntmTm.tmItalic = ptmW->ntmTm.tmItalic;
303 ptm16->ntmTm.tmUnderlined = ptmW->ntmTm.tmUnderlined;
304 ptm16->ntmTm.tmStruckOut = ptmW->ntmTm.tmStruckOut;
305 ptm16->ntmTm.tmPitchAndFamily = ptmW->ntmTm.tmPitchAndFamily;
306 ptm16->ntmTm.tmCharSet = ptmW->ntmTm.tmCharSet;
307 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
308 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
309 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
310 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
311 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
314 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, NEWTEXTMETRICEXA *ptmA )
316 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
317 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
318 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
319 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
320 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
321 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
325 /***********************************************************************
328 * Returns a '\0' terminated Unicode translation of str using the
329 * charset of the currently selected font in hdc. If count is -1 then
330 * str is assumed to be '\0' terminated, otherwise it contains the
331 * number of bytes to convert. If plenW is non-NULL, on return it
332 * will point to the number of WCHARs (excluding the '\0') that have
333 * been written. If pCP is non-NULL, on return it will point to the
334 * codepage used in the conversion.
335 * The caller should free the returned LPWSTR from the process
338 static LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
344 int charset = GetTextCharset(hdc);
346 /* Hmm, nicely designed api this one! */
347 if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
354 case DEFAULT_CHARSET:
365 /* FIXME: These have no place here, but because x11drv
366 enumerates fonts with these (made up) charsets some apps
367 might use them and then the FIXME below would become
368 annoying. Now we could pick the intended codepage for
369 each of these, but since it's broken anyway we'll just
370 use CP_ACP and hope it'll go away...
376 FIXME("Can't find codepage for charset %d\n", charset);
381 TRACE("charset %d => cp %d\n", charset, cp);
383 if(count == -1) count = strlen(str);
384 lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
385 strW = HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
386 MultiByteToWideChar(cp, 0, str, count, strW, lenW);
388 TRACE("mapped %s -> %s\n", debugstr_an(str, count), debugstr_wn(strW, lenW));
389 if(plenW) *plenW = lenW;
395 /***********************************************************************
396 * CreateFontIndirectA (GDI32.@)
398 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
403 FONT_LogFontAToW( plfA, &lfW );
404 return CreateFontIndirectW( &lfW );
406 return CreateFontIndirectW( NULL );
410 /***********************************************************************
411 * CreateFontIndirectW (GDI32.@)
413 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
420 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC,
421 (HGDIOBJ *)&hFont, &font_funcs )))
423 static const WCHAR ItalicW[] = {' ','I','t','a','l','i','c','\0'};
424 static const WCHAR BoldW[] = {' ','B','o','l','d','\0'};
425 WCHAR *pFaceNameItalicSuffix, *pFaceNameBoldSuffix;
426 WCHAR* pFaceNameSuffix = NULL;
428 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
430 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s %s => %p\n",
431 plf->lfHeight, plf->lfWidth,
432 plf->lfEscapement, plf->lfOrientation,
433 plf->lfPitchAndFamily,
434 plf->lfOutPrecision, plf->lfClipPrecision,
435 plf->lfQuality, plf->lfCharSet,
436 debugstr_w(plf->lfFaceName),
437 plf->lfWeight > 400 ? "Bold" : "",
438 plf->lfItalic ? "Italic" : "",
439 plf->lfUnderline ? "Underline" : "", hFont);
441 if (plf->lfEscapement != plf->lfOrientation) {
442 /* this should really depend on whether GM_ADVANCED is set */
443 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
444 WARN("orientation angle %f set to "
445 "escapement angle %f for new font %p\n",
446 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
449 pFaceNameItalicSuffix = strstrW(fontPtr->logfont.lfFaceName, ItalicW);
450 if (pFaceNameItalicSuffix) {
451 fontPtr->logfont.lfItalic = TRUE;
452 pFaceNameSuffix = pFaceNameItalicSuffix;
455 pFaceNameBoldSuffix = strstrW(fontPtr->logfont.lfFaceName, BoldW);
456 if (pFaceNameBoldSuffix) {
457 if (fontPtr->logfont.lfWeight < FW_BOLD) {
458 fontPtr->logfont.lfWeight = FW_BOLD;
460 if (!pFaceNameSuffix ||
461 (pFaceNameBoldSuffix < pFaceNameSuffix)) {
462 pFaceNameSuffix = pFaceNameBoldSuffix;
466 if (pFaceNameSuffix) *pFaceNameSuffix = 0;
468 GDI_ReleaseObj( hFont );
471 else WARN("(NULL) => NULL\n");
476 /*************************************************************************
477 * CreateFontA (GDI32.@)
479 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
480 INT orient, INT weight, DWORD italic,
481 DWORD underline, DWORD strikeout, DWORD charset,
482 DWORD outpres, DWORD clippres, DWORD quality,
483 DWORD pitch, LPCSTR name )
487 logfont.lfHeight = height;
488 logfont.lfWidth = width;
489 logfont.lfEscapement = esc;
490 logfont.lfOrientation = orient;
491 logfont.lfWeight = weight;
492 logfont.lfItalic = italic;
493 logfont.lfUnderline = underline;
494 logfont.lfStrikeOut = strikeout;
495 logfont.lfCharSet = charset;
496 logfont.lfOutPrecision = outpres;
497 logfont.lfClipPrecision = clippres;
498 logfont.lfQuality = quality;
499 logfont.lfPitchAndFamily = pitch;
502 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
504 logfont.lfFaceName[0] = '\0';
506 return CreateFontIndirectA( &logfont );
509 /*************************************************************************
510 * CreateFontW (GDI32.@)
512 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
513 INT orient, INT weight, DWORD italic,
514 DWORD underline, DWORD strikeout, DWORD charset,
515 DWORD outpres, DWORD clippres, DWORD quality,
516 DWORD pitch, LPCWSTR name )
520 logfont.lfHeight = height;
521 logfont.lfWidth = width;
522 logfont.lfEscapement = esc;
523 logfont.lfOrientation = orient;
524 logfont.lfWeight = weight;
525 logfont.lfItalic = italic;
526 logfont.lfUnderline = underline;
527 logfont.lfStrikeOut = strikeout;
528 logfont.lfCharSet = charset;
529 logfont.lfOutPrecision = outpres;
530 logfont.lfClipPrecision = clippres;
531 logfont.lfQuality = quality;
532 logfont.lfPitchAndFamily = pitch;
535 lstrcpynW(logfont.lfFaceName, name,
536 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
538 logfont.lfFaceName[0] = '\0';
540 return CreateFontIndirectW( &logfont );
544 /***********************************************************************
547 * If the driver supports vector fonts we create a gdi font first and
548 * then call the driver to give it a chance to supply its own device
549 * font. If the driver wants to do this it returns TRUE and we can
550 * delete the gdi font, if the driver wants to use the gdi font it
551 * should return FALSE, to signal an error return GDI_ERROR. For
552 * drivers that don't support vector fonts they must supply their own
555 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
558 DC *dc = DC_GetDCPtr( hdc );
562 if (dc->hFont != handle || dc->gdiFont == NULL)
564 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
565 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
568 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle, dc->gdiFont );
570 if (ret && dc->gdiFont) dc->gdiFont = 0;
572 if (ret == HGDI_ERROR)
573 ret = 0; /* SelectObject returns 0 on error */
579 GDI_ReleaseObj( hdc );
584 /***********************************************************************
587 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
592 FONT_LogFontWTo16( &font->logfont, &lf16 );
594 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
595 memcpy( buffer, &lf16, count );
599 /***********************************************************************
602 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
609 FONT_LogFontWToA( &font->logfont, &lfA );
611 if (count > sizeof(lfA)) count = sizeof(lfA);
612 memcpy( buffer, &lfA, count );
616 /***********************************************************************
619 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
623 return sizeof(LOGFONTW);
624 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
625 memcpy( buffer, &font->logfont, count );
630 /***********************************************************************
633 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
635 WineEngDestroyFontInstance( handle );
636 return GDI_FreeObject( handle, obj );
640 /***********************************************************************
641 * FONT_EnumInstance16
643 * Called by the device driver layer to pass font info
644 * down to the application.
646 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
647 * We have to use other types because of the FONTENUMPROCW definition.
649 static INT CALLBACK FONT_EnumInstance16( const LOGFONTW *plf, const TEXTMETRICW *ptm,
650 DWORD fType, LPARAM lp )
652 fontEnum16 *pfe = (fontEnum16*)lp;
656 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
657 pfe->lpLogFontParam->lfCharSet == plf->lfCharSet )
662 FONT_EnumLogFontExWTo16((const ENUMLOGFONTEXW *)plf, pfe->lpLogFont);
663 FONT_NewTextMetricExWTo16((const NEWTEXTMETRICEXW *)ptm, pfe->lpTextMetric);
664 pfe->dwFlags |= ENUM_CALLED;
665 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
667 args[6] = SELECTOROF(pfe->segLogFont);
668 args[5] = OFFSETOF(pfe->segLogFont);
669 args[4] = SELECTOROF(pfe->segTextMetric);
670 args[3] = OFFSETOF(pfe->segTextMetric);
672 args[1] = HIWORD(pfe->lpData);
673 args[0] = LOWORD(pfe->lpData);
674 WOWCallback16Ex( (DWORD)pfe->lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &result );
675 ret = LOWORD(result);
677 /* get the lock again and make sure the DC is still valid */
678 dc = DC_GetDCPtr( pfe->hdc );
679 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
681 if (dc) GDI_ReleaseObj( pfe->hdc );
682 pfe->hdc = 0; /* make sure we don't try to release it later on */
689 /***********************************************************************
692 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
693 * We have to use other types because of the FONTENUMPROCW definition.
695 static INT CALLBACK FONT_EnumInstance( const LOGFONTW *plf, const TEXTMETRICW *ptm,
696 DWORD fType, LPARAM lp )
698 fontEnum32 *pfe = (fontEnum32*)lp;
702 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
703 if((pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
704 pfe->lpLogFontParam->lfCharSet == plf->lfCharSet) &&
705 (!(fType & RASTER_FONTTYPE) || GetDeviceCaps(pfe->hdc, TEXTCAPS) & TC_RA_ABLE) )
707 /* convert font metrics */
708 ENUMLOGFONTEXA logfont;
709 NEWTEXTMETRICEXA tmA;
711 pfe->dwFlags |= ENUM_CALLED;
712 if (!(pfe->dwFlags & ENUM_UNICODE))
714 FONT_EnumLogFontExWToA( (const ENUMLOGFONTEXW *)plf, &logfont);
715 FONT_NewTextMetricExWToA( (const NEWTEXTMETRICEXW *)ptm, &tmA );
716 plf = (LOGFONTW *)&logfont.elfLogFont;
717 ptm = (TEXTMETRICW *)&tmA;
719 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
721 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
723 /* get the lock again and make sure the DC is still valid */
724 dc = DC_GetDCPtr( pfe->hdc );
725 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
727 if (dc) GDI_ReleaseObj( pfe->hdc );
728 pfe->hdc = 0; /* make sure we don't try to release it later on */
735 /***********************************************************************
736 * EnumFontFamiliesEx (GDI.613)
738 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
739 FONTENUMPROC16 efproc, LPARAM lParam,
744 DC* dc = DC_GetDCPtr( HDC_32(hDC) );
745 NEWTEXTMETRICEX16 tm16;
746 ENUMLOGFONTEX16 lf16;
751 FONT_LogFont16ToW(plf, &lfW);
753 fe16.hdc = HDC_32(hDC);
755 fe16.physDev = dc->physDev;
756 fe16.lpLogFontParam = plf;
757 fe16.lpEnumFunc = efproc;
758 fe16.lpData = lParam;
759 fe16.lpTextMetric = &tm16;
760 fe16.lpLogFont = &lf16;
761 fe16.segTextMetric = MapLS( &tm16 );
762 fe16.segLogFont = MapLS( &lf16 );
765 enum_gdi_fonts = GetDeviceCaps(fe16.hdc, TEXTCAPS) & TC_VA_ABLE;
767 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
774 ret = WineEngEnumFonts( &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
775 fe16.dwFlags &= ~ENUM_CALLED;
776 if (ret && dc->funcs->pEnumDeviceFonts) {
777 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
778 if(fe16.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
782 UnMapLS( fe16.segTextMetric );
783 UnMapLS( fe16.segLogFont );
784 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
788 /***********************************************************************
789 * FONT_EnumFontFamiliesEx
791 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
792 FONTENUMPROCW efproc,
793 LPARAM lParam, DWORD dwUnicode)
796 DC *dc = DC_GetDCPtr( hDC );
802 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
804 fe32.lpLogFontParam = plf;
805 fe32.lpEnumFunc = efproc;
806 fe32.lpData = lParam;
807 fe32.dwFlags = dwUnicode;
810 fe32.physDev = dc->physDev;
812 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
814 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
821 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
822 fe32.dwFlags &= ~ENUM_CALLED;
823 if (ret && dc->funcs->pEnumDeviceFonts) {
824 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
825 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
829 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
833 /***********************************************************************
834 * EnumFontFamiliesExW (GDI32.@)
836 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
837 FONTENUMPROCW efproc,
838 LPARAM lParam, DWORD dwFlags )
840 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
843 /***********************************************************************
844 * EnumFontFamiliesExA (GDI32.@)
846 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
847 FONTENUMPROCA efproc,
848 LPARAM lParam, DWORD dwFlags)
851 FONT_LogFontAToW( plf, &lfW );
853 return FONT_EnumFontFamiliesEx( hDC, &lfW, (FONTENUMPROCW)efproc, lParam, 0);
856 /***********************************************************************
857 * EnumFontFamilies (GDI.330)
859 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
860 FONTENUMPROC16 efproc, LPARAM lpData )
864 lf.lfCharSet = DEFAULT_CHARSET;
865 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
866 else lf.lfFaceName[0] = '\0';
868 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
871 /***********************************************************************
872 * EnumFontFamiliesA (GDI32.@)
874 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
875 FONTENUMPROCA efproc, LPARAM lpData )
879 lf.lfCharSet = DEFAULT_CHARSET;
880 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
881 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
883 return EnumFontFamiliesExA( hDC, &lf, efproc, lpData, 0 );
886 /***********************************************************************
887 * EnumFontFamiliesW (GDI32.@)
889 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
890 FONTENUMPROCW efproc, LPARAM lpData )
894 lf.lfCharSet = DEFAULT_CHARSET;
895 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
896 else lf.lfFaceName[0] = 0;
898 return EnumFontFamiliesExW( hDC, &lf, efproc, lpData, 0 );
901 /***********************************************************************
904 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
907 return EnumFontFamilies16( hDC, lpName, efproc, lpData );
910 /***********************************************************************
911 * EnumFontsA (GDI32.@)
913 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
916 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
919 /***********************************************************************
920 * EnumFontsW (GDI32.@)
922 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
925 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
929 /***********************************************************************
930 * GetTextCharacterExtra (GDI32.@)
932 INT WINAPI GetTextCharacterExtra( HDC hdc )
935 DC *dc = DC_GetDCPtr( hdc );
936 if (!dc) return 0x80000000;
938 GDI_ReleaseObj( hdc );
943 /***********************************************************************
944 * SetTextCharacterExtra (GDI32.@)
946 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
949 DC * dc = DC_GetDCPtr( hdc );
950 if (!dc) return 0x80000000;
951 if (dc->funcs->pSetTextCharacterExtra)
952 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
955 prev = dc->charExtra;
956 dc->charExtra = extra;
958 GDI_ReleaseObj( hdc );
963 /***********************************************************************
964 * SetTextJustification (GDI32.@)
966 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
969 DC * dc = DC_GetDCPtr( hdc );
970 if (!dc) return FALSE;
971 if (dc->funcs->pSetTextJustification)
972 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
975 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
976 if (!extra) breaks = 0;
979 dc->breakExtra = extra / breaks;
980 dc->breakRem = extra - (breaks * dc->breakExtra);
988 GDI_ReleaseObj( hdc );
993 /***********************************************************************
994 * GetTextFaceA (GDI32.@)
996 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
998 INT res = GetTextFaceW(hdc, 0, NULL);
999 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
1000 GetTextFaceW( hdc, res, nameW );
1004 if (count && !WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count, NULL, NULL))
1009 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
1010 HeapFree( GetProcessHeap(), 0, nameW );
1014 /***********************************************************************
1015 * GetTextFaceW (GDI32.@)
1017 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
1022 DC * dc = DC_GetDCPtr( hdc );
1026 ret = WineEngGetTextFace(dc->gdiFont, count, name);
1027 else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1031 lstrcpynW( name, font->logfont.lfFaceName, count );
1032 ret = strlenW(name);
1034 else ret = strlenW(font->logfont.lfFaceName) + 1;
1035 GDI_ReleaseObj( dc->hFont );
1037 GDI_ReleaseObj( hdc );
1042 /***********************************************************************
1043 * GetTextExtentPoint32A (GDI32.@)
1045 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1050 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1053 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1054 HeapFree( GetProcessHeap(), 0, p );
1057 TRACE("(%p %s %d %p): returning %ld x %ld\n",
1058 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1063 /***********************************************************************
1064 * GetTextExtentPoint32W [GDI32.@]
1066 * Computes width/height for a string.
1068 * Computes width and height of the specified string.
1074 BOOL WINAPI GetTextExtentPoint32W(
1075 HDC hdc, /* [in] Handle of device context */
1076 LPCWSTR str, /* [in] Address of text string */
1077 INT count, /* [in] Number of characters in string */
1078 LPSIZE size) /* [out] Address of structure for string size */
1081 DC * dc = DC_GetDCPtr( hdc );
1082 if (!dc) return FALSE;
1085 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1086 else if(dc->funcs->pGetTextExtentPoint)
1087 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1091 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1092 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1093 size->cx += count * dc->charExtra + dc->breakRem;
1096 GDI_ReleaseObj( hdc );
1098 TRACE("(%p %s %d %p): returning %ld x %ld\n",
1099 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1103 /***********************************************************************
1104 * GetTextExtentPointI [GDI32.@]
1106 * Computes width and height of the array of glyph indices.
1112 BOOL WINAPI GetTextExtentPointI(
1113 HDC hdc, /* [in] Handle of device context */
1114 const WORD *indices, /* [in] Address of glyph index array */
1115 INT count, /* [in] Number of glyphs in array */
1116 LPSIZE size) /* [out] Address of structure for string size */
1119 DC * dc = DC_GetDCPtr( hdc );
1120 if (!dc) return FALSE;
1123 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1124 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1125 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1126 size->cx += count * dc->charExtra;
1128 else if(dc->funcs->pGetTextExtentPoint) {
1129 FIXME("calling GetTextExtentPoint\n");
1130 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1133 GDI_ReleaseObj( hdc );
1135 TRACE("(%p %p %d %p): returning %ld x %ld\n",
1136 hdc, indices, count, size, size->cx, size->cy );
1141 /***********************************************************************
1142 * GetTextExtentPointA (GDI32.@)
1144 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1147 TRACE("not bug compatible.\n");
1148 return GetTextExtentPoint32A( hdc, str, count, size );
1151 /***********************************************************************
1152 * GetTextExtentPointW (GDI32.@)
1154 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1157 TRACE("not bug compatible.\n");
1158 return GetTextExtentPoint32W( hdc, str, count, size );
1162 /***********************************************************************
1163 * GetTextExtentExPointA (GDI32.@)
1165 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1166 INT maxExt, LPINT lpnFit,
1167 LPINT alpDx, LPSIZE size )
1171 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1172 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1173 if (lpnFit) *lpnFit = WideCharToMultiByte(CP_ACP,0,p,*lpnFit,NULL,0,NULL,NULL);
1174 HeapFree( GetProcessHeap(), 0, p );
1179 /***********************************************************************
1180 * GetTextExtentExPointW (GDI32.@)
1182 * Return the size of the string as it would be if it was output properly by
1185 * This should include
1186 * - Intercharacter spacing
1187 * - justification spacing (not yet done)
1188 * - kerning? see below
1190 * Kerning. Since kerning would be carried out by the rendering code it should
1191 * be done by the driver. However they don't support it yet. Also I am not
1192 * yet persuaded that (certainly under Win95) any kerning is actually done.
1194 * str: According to MSDN this should be null-terminated. That is not true; a
1195 * null will not terminate it early.
1196 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1197 * than count. I have seen it be either the size of the full string or
1198 * 1 less than the size of the full string. I have not seen it bear any
1199 * resemblance to the portion that would fit.
1200 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1201 * trailing intercharacter spacing and any trailing justification.
1204 * Currently we do this by measuring each character etc. We should do it by
1205 * passing the request to the driver, perhaps by extending the
1206 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1207 * thinking about kerning issues and rounding issues in the justification.
1210 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1211 INT maxExt, LPINT lpnFit,
1212 LPINT alpDx, LPSIZE size )
1214 int index, nFit, extent;
1218 TRACE("(%p, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1220 size->cx = size->cy = nFit = extent = 0;
1221 for(index = 0; index < count; index++)
1223 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1224 /* GetTextExtentPoint includes intercharacter spacing. */
1225 /* FIXME - justification needs doing yet. Remember that the base
1226 * data will not be in logical coordinates.
1229 if( !lpnFit || extent <= maxExt )
1230 /* It is allowed to be equal. */
1233 if( alpDx ) alpDx[index] = extent;
1235 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1239 if(lpnFit) *lpnFit = nFit;
1242 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1248 /***********************************************************************
1249 * GetTextMetricsA (GDI32.@)
1251 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1255 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1256 FONT_TextMetricWToA( &tm32, metrics );
1260 /***********************************************************************
1261 * GetTextMetricsW (GDI32.@)
1263 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1266 DC * dc = DC_GetDCPtr( hdc );
1267 if (!dc) return FALSE;
1270 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1271 else if (dc->funcs->pGetTextMetrics)
1272 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1276 /* device layer returns values in device units
1277 * therefore we have to convert them to logical */
1279 #define WDPTOLP(x) ((x<0)? \
1280 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1281 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1282 #define HDPTOLP(y) ((y<0)? \
1283 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1284 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1286 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1287 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1288 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1289 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1290 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1291 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1292 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1293 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1297 TRACE("text metrics:\n"
1298 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1299 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1300 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1301 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1302 " PitchAndFamily = %02x\n"
1303 " --------------------\n"
1304 " InternalLeading = %li\n"
1308 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1309 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1310 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1311 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1312 metrics->tmPitchAndFamily,
1313 metrics->tmInternalLeading,
1316 metrics->tmHeight );
1318 GDI_ReleaseObj( hdc );
1323 /***********************************************************************
1324 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1327 * lpOTM should be LPOUTLINETEXTMETRIC
1330 * Success: Non-zero or size of required buffer
1333 UINT16 WINAPI GetOutlineTextMetrics16(
1334 HDC16 hdc, /* [in] Handle of device context */
1335 UINT16 cbData, /* [in] Size of metric data array */
1336 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1338 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1343 /***********************************************************************
1344 * GetOutlineTextMetricsA (GDI32.@)
1345 * Gets metrics for TrueType fonts.
1348 * If the supplied buffer isn't big enough Windows partially fills it up to
1349 * its given length and returns that length.
1352 * Success: Non-zero or size of required buffer
1355 UINT WINAPI GetOutlineTextMetricsA(
1356 HDC hdc, /* [in] Handle of device context */
1357 UINT cbData, /* [in] Size of metric data array */
1358 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1360 char buf[512], *ptr;
1362 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1363 OUTLINETEXTMETRICA *output = lpOTM;
1366 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1368 if(ret > sizeof(buf))
1369 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1370 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1372 needed = sizeof(OUTLINETEXTMETRICA);
1373 if(lpOTMW->otmpFamilyName)
1374 needed += WideCharToMultiByte(CP_ACP, 0,
1375 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1376 NULL, 0, NULL, NULL);
1377 if(lpOTMW->otmpFaceName)
1378 needed += WideCharToMultiByte(CP_ACP, 0,
1379 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1380 NULL, 0, NULL, NULL);
1381 if(lpOTMW->otmpStyleName)
1382 needed += WideCharToMultiByte(CP_ACP, 0,
1383 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1384 NULL, 0, NULL, NULL);
1385 if(lpOTMW->otmpFullName)
1386 needed += WideCharToMultiByte(CP_ACP, 0,
1387 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1388 NULL, 0, NULL, NULL);
1395 TRACE("needed = %d\n", needed);
1397 /* Since the supplied buffer isn't big enough, we'll alloc one
1398 that is and memcpy the first cbData bytes into the lpOTM at
1400 output = HeapAlloc(GetProcessHeap(), 0, needed);
1402 ret = output->otmSize = min(needed, cbData);
1403 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &output->otmTextMetrics );
1404 output->otmFiller = 0;
1405 output->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1406 output->otmfsSelection = lpOTMW->otmfsSelection;
1407 output->otmfsType = lpOTMW->otmfsType;
1408 output->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1409 output->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1410 output->otmItalicAngle = lpOTMW->otmItalicAngle;
1411 output->otmEMSquare = lpOTMW->otmEMSquare;
1412 output->otmAscent = lpOTMW->otmAscent;
1413 output->otmDescent = lpOTMW->otmDescent;
1414 output->otmLineGap = lpOTMW->otmLineGap;
1415 output->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1416 output->otmsXHeight = lpOTMW->otmsXHeight;
1417 output->otmrcFontBox = lpOTMW->otmrcFontBox;
1418 output->otmMacAscent = lpOTMW->otmMacAscent;
1419 output->otmMacDescent = lpOTMW->otmMacDescent;
1420 output->otmMacLineGap = lpOTMW->otmMacLineGap;
1421 output->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1422 output->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1423 output->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1424 output->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1425 output->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1426 output->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1427 output->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1428 output->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1429 output->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1432 ptr = (char*)(output + 1);
1433 left = needed - sizeof(*output);
1435 if(lpOTMW->otmpFamilyName) {
1436 output->otmpFamilyName = (LPSTR)(ptr - (char*)output);
1437 len = WideCharToMultiByte(CP_ACP, 0,
1438 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1439 ptr, left, NULL, NULL);
1443 output->otmpFamilyName = 0;
1445 if(lpOTMW->otmpFaceName) {
1446 output->otmpFaceName = (LPSTR)(ptr - (char*)output);
1447 len = WideCharToMultiByte(CP_ACP, 0,
1448 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1449 ptr, left, NULL, NULL);
1453 output->otmpFaceName = 0;
1455 if(lpOTMW->otmpStyleName) {
1456 output->otmpStyleName = (LPSTR)(ptr - (char*)output);
1457 len = WideCharToMultiByte(CP_ACP, 0,
1458 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1459 ptr, left, NULL, NULL);
1463 output->otmpStyleName = 0;
1465 if(lpOTMW->otmpFullName) {
1466 output->otmpFullName = (LPSTR)(ptr - (char*)output);
1467 len = WideCharToMultiByte(CP_ACP, 0,
1468 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1469 ptr, left, NULL, NULL);
1472 output->otmpFullName = 0;
1476 if(output != lpOTM) {
1477 memcpy(lpOTM, output, cbData);
1478 HeapFree(GetProcessHeap(), 0, output);
1482 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1483 HeapFree(GetProcessHeap(), 0, lpOTMW);
1489 /***********************************************************************
1490 * GetOutlineTextMetricsW [GDI32.@]
1492 UINT WINAPI GetOutlineTextMetricsW(
1493 HDC hdc, /* [in] Handle of device context */
1494 UINT cbData, /* [in] Size of metric data array */
1495 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1497 DC *dc = DC_GetDCPtr( hdc );
1498 OUTLINETEXTMETRICW *output = lpOTM;
1501 TRACE("(%p,%d,%p)\n", hdc, cbData, lpOTM);
1505 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, output);
1508 output = HeapAlloc(GetProcessHeap(), 0, ret);
1509 WineEngGetOutlineTextMetrics(dc->gdiFont, ret, output);
1512 #define WDPTOLP(x) ((x<0)? \
1513 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1514 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1515 #define HDPTOLP(y) ((y<0)? \
1516 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1517 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1519 output->otmTextMetrics.tmHeight = HDPTOLP(output->otmTextMetrics.tmHeight);
1520 output->otmTextMetrics.tmAscent = HDPTOLP(output->otmTextMetrics.tmAscent);
1521 output->otmTextMetrics.tmDescent = HDPTOLP(output->otmTextMetrics.tmDescent);
1522 output->otmTextMetrics.tmInternalLeading = HDPTOLP(output->otmTextMetrics.tmInternalLeading);
1523 output->otmTextMetrics.tmExternalLeading = HDPTOLP(output->otmTextMetrics.tmExternalLeading);
1524 output->otmTextMetrics.tmAveCharWidth = WDPTOLP(output->otmTextMetrics.tmAveCharWidth);
1525 output->otmTextMetrics.tmMaxCharWidth = WDPTOLP(output->otmTextMetrics.tmMaxCharWidth);
1526 output->otmTextMetrics.tmOverhang = WDPTOLP(output->otmTextMetrics.tmOverhang);
1527 output->otmAscent = HDPTOLP(output->otmAscent);
1528 output->otmDescent = HDPTOLP(output->otmDescent);
1529 output->otmLineGap = HDPTOLP(output->otmLineGap);
1530 output->otmsCapEmHeight = HDPTOLP(output->otmsCapEmHeight);
1531 output->otmsXHeight = HDPTOLP(output->otmsXHeight);
1532 output->otmrcFontBox.top = HDPTOLP(output->otmrcFontBox.top);
1533 output->otmrcFontBox.bottom = HDPTOLP(output->otmrcFontBox.bottom);
1534 output->otmrcFontBox.left = WDPTOLP(output->otmrcFontBox.left);
1535 output->otmrcFontBox.right = WDPTOLP(output->otmrcFontBox.right);
1536 output->otmMacAscent = HDPTOLP(output->otmMacAscent);
1537 output->otmMacDescent = HDPTOLP(output->otmMacDescent);
1538 output->otmMacLineGap = HDPTOLP(output->otmMacLineGap);
1539 output->otmptSubscriptSize.x = WDPTOLP(output->otmptSubscriptSize.x);
1540 output->otmptSubscriptSize.y = HDPTOLP(output->otmptSubscriptSize.y);
1541 output->otmptSubscriptOffset.x = WDPTOLP(output->otmptSubscriptOffset.x);
1542 output->otmptSubscriptOffset.y = HDPTOLP(output->otmptSubscriptOffset.y);
1543 output->otmptSuperscriptSize.x = WDPTOLP(output->otmptSuperscriptSize.x);
1544 output->otmptSuperscriptSize.y = HDPTOLP(output->otmptSuperscriptSize.y);
1545 output->otmptSuperscriptOffset.x = WDPTOLP(output->otmptSuperscriptOffset.x);
1546 output->otmptSuperscriptOffset.y = HDPTOLP(output->otmptSuperscriptOffset.y);
1547 output->otmsStrikeoutSize = HDPTOLP(output->otmsStrikeoutSize);
1548 output->otmsStrikeoutPosition = HDPTOLP(output->otmsStrikeoutPosition);
1549 output->otmsUnderscoreSize = HDPTOLP(output->otmsUnderscoreSize);
1550 output->otmsUnderscorePosition = HDPTOLP(output->otmsUnderscorePosition);
1553 if(output != lpOTM) {
1554 memcpy(lpOTM, output, cbData);
1555 HeapFree(GetProcessHeap(), 0, output);
1561 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1562 but really this should just be a return 0. */
1564 ret = sizeof(*lpOTM);
1569 memset(lpOTM, 0, ret);
1570 lpOTM->otmSize = sizeof(*lpOTM);
1571 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1573 Further fill of the structure not implemented,
1574 Needs real values for the structure members
1579 GDI_ReleaseObj(hdc);
1584 /***********************************************************************
1585 * GetCharWidthW (GDI32.@)
1586 * GetCharWidth32W (GDI32.@)
1588 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1593 DC * dc = DC_GetDCPtr( hdc );
1594 if (!dc) return FALSE;
1597 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1598 else if (dc->funcs->pGetCharWidth)
1599 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1603 /* convert device units to logical */
1604 for( i = firstChar; i <= lastChar; i++, buffer++ )
1605 *buffer = INTERNAL_XDSTOWS(dc, *buffer);
1608 GDI_ReleaseObj( hdc );
1613 /***********************************************************************
1614 * GetCharWidthA (GDI32.@)
1615 * GetCharWidth32A (GDI32.@)
1617 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1620 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1625 if(count <= 0) return FALSE;
1627 str = HeapAlloc(GetProcessHeap(), 0, count);
1628 for(i = 0; i < count; i++)
1629 str[i] = (BYTE)(firstChar + i);
1631 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1633 for(i = 0; i < wlen; i++)
1635 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1643 HeapFree(GetProcessHeap(), 0, str);
1644 HeapFree(GetProcessHeap(), 0, wstr);
1650 /***********************************************************************
1651 * ExtTextOutA (GDI32.@)
1653 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
1654 const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
1658 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
1663 unsigned int i = 0, j = 0;
1665 lpDxW = (LPINT)HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
1667 if(IsDBCSLeadByteEx(codepage, str[i])) {
1668 lpDxW[j++] = lpDx[i] + lpDx[i+1];
1671 lpDxW[j++] = lpDx[i];
1677 ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
1679 HeapFree( GetProcessHeap(), 0, p );
1680 HeapFree( GetProcessHeap(), 0, lpDxW );
1685 /***********************************************************************
1686 * ExtTextOutW (GDI32.@)
1688 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
1689 const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
1692 DC * dc = DC_GetDCUpdate( hdc );
1695 if(PATH_IsPathOpen(dc->path))
1696 FIXME("called on an open path\n");
1697 else if(dc->funcs->pExtTextOut)
1699 if( !(flags&(ETO_GLYPH_INDEX|ETO_IGNORELANGUAGE)) && BidiAvail && count>0 )
1701 /* The caller did not specify that language processing was already done.
1703 LPWSTR lpReorderedString=HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
1705 BIDI_Reorder( str, count, GCP_REORDER,
1706 ((flags&ETO_RTLREADING)!=0 || (GetTextAlign(hdc)&TA_RTLREADING)!=0)?
1707 WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR,
1708 lpReorderedString, count, NULL );
1710 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags|ETO_IGNORELANGUAGE,
1711 lprect,lpReorderedString,count,lpDx,dc->breakExtra);
1712 HeapFree(GetProcessHeap(), 0, lpReorderedString);
1714 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,
1715 lpDx,dc->breakExtra);
1717 GDI_ReleaseObj( hdc );
1723 /***********************************************************************
1724 * TextOutA (GDI32.@)
1726 BOOL WINAPI TextOutA( HDC hdc, INT x, INT y, LPCSTR str, INT count )
1728 return ExtTextOutA( hdc, x, y, 0, NULL, str, count, NULL );
1732 /***********************************************************************
1733 * TextOutW (GDI32.@)
1735 BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
1737 return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
1741 /***********************************************************************
1742 * PolyTextOutA (GDI32.@)
1744 * Draw several Strings
1746 BOOL WINAPI PolyTextOutA ( HDC hdc, /* [in] Handle to device context */
1747 PPOLYTEXTA pptxt, /* [in] Array of strings */
1748 INT cStrings ) /* [in] Number of strings in array */
1750 for (; cStrings>0; cStrings--, pptxt++)
1751 if (!ExtTextOutA( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
1758 /***********************************************************************
1759 * PolyTextOutW (GDI32.@)
1761 * Draw several Strings
1763 BOOL WINAPI PolyTextOutW ( HDC hdc, /* [in] Handle to device context */
1764 PPOLYTEXTW pptxt, /* [in] Array of strings */
1765 INT cStrings ) /* [in] Number of strings in array */
1767 for (; cStrings>0; cStrings--, pptxt++)
1768 if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
1774 /* FIXME: all following APIs ******************************************/
1777 /***********************************************************************
1778 * SetMapperFlags (GDI32.@)
1780 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1782 DC *dc = DC_GetDCPtr( hDC );
1785 if(dc->funcs->pSetMapperFlags)
1786 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1788 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1789 GDI_ReleaseObj( hDC );
1793 /***********************************************************************
1794 * GetAspectRatioFilterEx (GDI.486)
1796 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1798 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1802 /***********************************************************************
1803 * GetAspectRatioFilterEx (GDI32.@)
1805 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1807 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1812 /***********************************************************************
1813 * GetCharABCWidthsA (GDI32.@)
1815 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1818 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1823 if(count <= 0) return FALSE;
1825 str = HeapAlloc(GetProcessHeap(), 0, count);
1826 for(i = 0; i < count; i++)
1827 str[i] = (BYTE)(firstChar + i);
1829 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1831 for(i = 0; i < wlen; i++)
1833 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1841 HeapFree(GetProcessHeap(), 0, str);
1842 HeapFree(GetProcessHeap(), 0, wstr);
1848 /******************************************************************************
1849 * GetCharABCWidthsW [GDI32.@]
1851 * Retrieves widths of characters in range.
1854 * hdc [I] Handle of device context
1855 * firstChar [I] First character in range to query
1856 * lastChar [I] Last character in range to query
1857 * abc [O] Address of character-width structure
1860 * Only works with TrueType fonts
1866 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1869 DC *dc = DC_GetDCPtr(hdc);
1874 ret = WineEngGetCharABCWidths( dc->gdiFont, firstChar, lastChar, abc );
1880 /* convert device units to logical */
1881 for( i = firstChar; i <= lastChar; i++, abc++ ) {
1882 abc->abcA = INTERNAL_XDSTOWS(dc, abc->abcA);
1883 abc->abcB = INTERNAL_XDSTOWS(dc, abc->abcB);
1884 abc->abcC = INTERNAL_XDSTOWS(dc, abc->abcC);
1889 GDI_ReleaseObj(hdc);
1894 /***********************************************************************
1895 * GetGlyphOutline (GDI.309)
1897 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1898 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1899 LPVOID lpBuffer, const MAT2 *lpmat2 )
1901 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1902 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1903 return ~0UL; /* failure */
1907 /***********************************************************************
1908 * GetGlyphOutlineA (GDI32.@)
1910 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1911 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1912 LPVOID lpBuffer, const MAT2 *lpmat2 )
1918 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1919 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1923 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1925 HeapFree(GetProcessHeap(), 0, p);
1929 /***********************************************************************
1930 * GetGlyphOutlineW (GDI32.@)
1932 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1933 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1934 LPVOID lpBuffer, const MAT2 *lpmat2 )
1936 DC *dc = DC_GetDCPtr(hdc);
1939 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1940 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1942 if(!dc) return GDI_ERROR;
1945 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1946 cbBuffer, lpBuffer, lpmat2);
1950 GDI_ReleaseObj(hdc);
1955 /***********************************************************************
1956 * CreateScalableFontResourceA (GDI32.@)
1958 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1959 LPCSTR lpszResourceFile,
1960 LPCSTR lpszFontFile,
1961 LPCSTR lpszCurrentPath )
1965 /* fHidden=1 - only visible for the calling app, read-only, not
1966 * enumbered with EnumFonts/EnumFontFamilies
1967 * lpszCurrentPath can be NULL
1969 FIXME("(%ld,%s,%s,%s): stub\n",
1970 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1971 debugstr_a(lpszCurrentPath) );
1973 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1974 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
1976 SetLastError(ERROR_FILE_EXISTS);
1979 return FALSE; /* create failed */
1982 /***********************************************************************
1983 * CreateScalableFontResourceW (GDI32.@)
1985 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1986 LPCWSTR lpszResourceFile,
1987 LPCWSTR lpszFontFile,
1988 LPCWSTR lpszCurrentPath )
1990 FIXME("(%ld,%p,%p,%p): stub\n",
1991 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1992 return FALSE; /* create failed */
1996 /*************************************************************************
1997 * GetRasterizerCaps (GDI32.@)
1999 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
2001 lprs->nSize = sizeof(RASTERIZER_STATUS);
2002 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
2003 lprs->nLanguageID = 0;
2008 /*************************************************************************
2009 * GetKerningPairsA (GDI32.@)
2011 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2012 LPKERNINGPAIR lpKerningPairs )
2014 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
2018 /*************************************************************************
2019 * GetKerningPairsW (GDI32.@)
2021 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2022 LPKERNINGPAIR lpKerningPairs )
2025 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2026 for (i = 0; i < cPairs; i++)
2027 lpKerningPairs[i].iKernAmount = 0;
2031 /*************************************************************************
2032 * TranslateCharsetInfo [GDI32.@]
2034 * Fills a CHARSETINFO structure for a character set, code page, or
2035 * font. This allows making the correspondance between different labelings
2036 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2037 * of the same encoding.
2039 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2040 * only one codepage should be set in *lpSrc.
2043 * TRUE on success, FALSE on failure.
2046 BOOL WINAPI TranslateCharsetInfo(
2047 LPDWORD lpSrc, /* [in]
2048 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2049 if flags == TCI_SRCCHARSET: a character set value
2050 if flags == TCI_SRCCODEPAGE: a code page value
2052 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2053 DWORD flags /* [in] determines interpretation of lpSrc */)
2057 case TCI_SRCFONTSIG:
2058 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2060 case TCI_SRCCODEPAGE:
2061 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2063 case TCI_SRCCHARSET:
2064 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2069 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2070 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2074 /*************************************************************************
2075 * GetFontLanguageInfo (GDI32.@)
2077 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
2079 FONTSIGNATURE fontsig;
2080 static const DWORD GCP_DBCS_MASK=0x003F0000,
2081 GCP_DIACRITIC_MASK=0x00000000,
2082 FLI_GLYPHS_MASK=0x00000000,
2083 GCP_GLYPHSHAPE_MASK=0x00000040,
2084 GCP_KASHIDA_MASK=0x00000000,
2085 GCP_LIGATE_MASK=0x00000000,
2086 GCP_USEKERNING_MASK=0x00000000,
2087 GCP_REORDER_MASK=0x00000060;
2091 GetTextCharsetInfo( hdc, &fontsig, 0 );
2092 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
2094 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
2097 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
2098 result|=GCP_DIACRITIC;
2100 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
2103 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
2104 result|=GCP_GLYPHSHAPE;
2106 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
2107 result|=GCP_KASHIDA;
2109 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
2112 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
2113 result|=GCP_USEKERNING;
2115 /* this might need a test for a HEBREW- or ARABIC_CHARSET as well */
2116 if( GetTextAlign( hdc) & TA_RTLREADING )
2117 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
2118 result|=GCP_REORDER;
2124 /*************************************************************************
2125 * GetFontData [GDI32.@]
2127 * Retrieve data for TrueType font.
2131 * success: Number of bytes returned
2132 * failure: GDI_ERROR
2136 * Calls SetLastError()
2139 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2140 LPVOID buffer, DWORD length)
2142 DC *dc = DC_GetDCPtr(hdc);
2143 DWORD ret = GDI_ERROR;
2145 if(!dc) return GDI_ERROR;
2148 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2150 GDI_ReleaseObj(hdc);
2154 /*************************************************************************
2155 * GetGlyphIndicesA [GDI32.@]
2157 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2158 LPWORD pgi, DWORD flags)
2164 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
2165 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2167 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2168 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2169 HeapFree(GetProcessHeap(), 0, lpstrW);
2174 /*************************************************************************
2175 * GetGlyphIndicesW [GDI32.@]
2177 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2178 LPWORD pgi, DWORD flags)
2180 DC *dc = DC_GetDCPtr(hdc);
2181 DWORD ret = GDI_ERROR;
2183 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
2184 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2186 if(!dc) return GDI_ERROR;
2189 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2191 GDI_ReleaseObj(hdc);
2195 /*************************************************************************
2196 * GetCharacterPlacementA [GDI32.@]
2199 * the web browser control of ie4 calls this with dwFlags=0
2202 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2203 INT nMaxExtent, GCP_RESULTSA *lpResults,
2208 GCP_RESULTSW resultsW;
2212 TRACE("%s, %d, %d, 0x%08lx\n",
2213 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2215 /* both structs are equal in size */
2216 memcpy(&resultsW, lpResults, sizeof(resultsW));
2218 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2219 if(lpResults->lpOutString)
2220 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
2222 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2224 if(lpResults->lpOutString) {
2225 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2226 lpResults->lpOutString, uCount, NULL, NULL );
2229 HeapFree(GetProcessHeap(), 0, lpStringW);
2230 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2235 /*************************************************************************
2236 * GetCharacterPlacementW [GDI32.@]
2238 * Retrieve information about a string. This includes the width, reordering,
2239 * Glyphing and so on.
2243 * The width and height of the string if successful, 0 if failed.
2247 * All flags except GCP_REORDER are not yet implemented.
2248 * Reordering is not 100% complient to the Windows BiDi method.
2249 * Caret positioning is not yet implemented for BiDi.
2250 * Classes are not yet implemented.
2254 GetCharacterPlacementW(
2255 HDC hdc, /* [in] Device context for which the rendering is to be done */
2256 LPCWSTR lpString, /* [in] The string for which information is to be returned */
2257 INT uCount, /* [in] Number of WORDS in string. */
2258 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
2259 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
2260 DWORD dwFlags /* [in] Flags specifying how to process the string */
2267 TRACE("%s, %d, %d, 0x%08lx\n",
2268 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2270 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2271 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2272 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2273 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2274 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2276 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
2277 if(lpResults->lpClass) FIXME("classes not implemented\n");
2278 if (lpResults->lpCaretPos && (dwFlags & GCP_REORDER))
2279 FIXME("Caret positions for complex scripts not implemented\n");
2281 nSet = (UINT)uCount;
2282 if(nSet > lpResults->nGlyphs)
2283 nSet = lpResults->nGlyphs;
2285 /* return number of initialized fields */
2286 lpResults->nGlyphs = nSet;
2288 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
2290 /* Treat the case where no special handling was requested in a fastpath way */
2291 /* copy will do if the GCP_REORDER flag is not set */
2292 if(lpResults->lpOutString)
2293 strncpyW( lpResults->lpOutString, lpString, nSet );
2295 if(lpResults->lpOrder)
2297 for(i = 0; i < nSet; i++)
2298 lpResults->lpOrder[i] = i;
2302 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2303 nSet, lpResults->lpOrder );
2306 /* FIXME: Will use the placement chars */
2307 if (lpResults->lpDx)
2310 for (i = 0; i < nSet; i++)
2312 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2313 lpResults->lpDx[i]= c;
2317 if (lpResults->lpCaretPos && !(dwFlags & GCP_REORDER))
2321 lpResults->lpCaretPos[0] = 0;
2322 for (i = 1; i < nSet; i++)
2323 if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
2324 lpResults->lpCaretPos[i] = (pos += size.cx);
2327 if(lpResults->lpGlyphs)
2328 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2330 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2331 ret = MAKELONG(size.cx, size.cy);
2336 /*************************************************************************
2337 * GetCharABCWidthsFloatA [GDI32.@]
2339 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2342 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2346 /*************************************************************************
2347 * GetCharABCWidthsFloatW [GDI32.@]
2349 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2350 UINT iLastChar, LPABCFLOAT lpABCF)
2352 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2356 /*************************************************************************
2357 * GetCharWidthFloatA [GDI32.@]
2359 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2360 UINT iLastChar, PFLOAT pxBuffer)
2362 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2366 /*************************************************************************
2367 * GetCharWidthFloatW [GDI32.@]
2369 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2370 UINT iLastChar, PFLOAT pxBuffer)
2372 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2377 /***********************************************************************
2379 * Font Resource API *
2381 ***********************************************************************/
2383 /***********************************************************************
2384 * AddFontResourceA (GDI32.@)
2386 INT WINAPI AddFontResourceA( LPCSTR str )
2388 return AddFontResourceExA( str, 0, NULL);
2391 /***********************************************************************
2392 * AddFontResourceW (GDI32.@)
2394 INT WINAPI AddFontResourceW( LPCWSTR str )
2396 return AddFontResourceExW(str, 0, NULL);
2400 /***********************************************************************
2401 * AddFontResourceExA (GDI32.@)
2403 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2405 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2406 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2409 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2410 ret = AddFontResourceExW(strW, fl, pdv);
2411 HeapFree(GetProcessHeap(), 0, strW);
2415 /***********************************************************************
2416 * AddFontResourceExW (GDI32.@)
2418 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2420 return WineEngAddFontResourceEx(str, fl, pdv);
2423 /***********************************************************************
2424 * RemoveFontResourceA (GDI32.@)
2426 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2428 return RemoveFontResourceExA(str, 0, 0);
2431 /***********************************************************************
2432 * RemoveFontResourceW (GDI32.@)
2434 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2436 return RemoveFontResourceExW(str, 0, 0);
2439 /***********************************************************************
2440 * RemoveFontResourceExA (GDI32.@)
2442 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2444 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2445 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2448 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2449 ret = RemoveFontResourceExW(strW, fl, pdv);
2450 HeapFree(GetProcessHeap(), 0, strW);
2454 /***********************************************************************
2455 * RemoveFontResourceExW (GDI32.@)
2457 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2459 return WineEngRemoveFontResourceEx(str, fl, pdv);
2462 /***********************************************************************
2463 * GetTextCharset (GDI32.@)
2465 UINT WINAPI GetTextCharset(HDC hdc)
2467 /* MSDN docs say this is equivalent */
2468 return GetTextCharsetInfo(hdc, NULL, 0);
2471 /***********************************************************************
2472 * GetTextCharsetInfo (GDI32.@)
2474 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2476 UINT ret = DEFAULT_CHARSET;
2477 DC *dc = DC_GetDCPtr(hdc);
2482 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2484 GDI_ReleaseObj(hdc);
2487 if (ret == DEFAULT_CHARSET && fs)
2488 memset(fs, 0, sizeof(FONTSIGNATURE));