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.@)
1655 BOOL WINAPI ExtTextOutA( HDC hdc, INT x, INT y, UINT flags,
1656 const RECT *lprect, LPCSTR str, UINT count, const INT *lpDx )
1660 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, &codepage);
1665 unsigned int i = 0, j = 0;
1667 lpDxW = HeapAlloc( GetProcessHeap(), 0, wlen*sizeof(INT));
1669 if(IsDBCSLeadByteEx(codepage, str[i])) {
1670 lpDxW[j++] = lpDx[i] + lpDx[i+1];
1673 lpDxW[j++] = lpDx[i];
1679 ret = ExtTextOutW( hdc, x, y, flags, lprect, p, wlen, lpDxW );
1681 HeapFree( GetProcessHeap(), 0, p );
1682 HeapFree( GetProcessHeap(), 0, lpDxW );
1687 /***********************************************************************
1688 * ExtTextOutW (GDI32.@)
1690 * Draws text using the currently selected font, background color, and text color.
1694 * x,y [I] coordinates of string
1696 * ETO_GRAYED - undocumented on MSDN
1697 * ETO_OPAQUE - use background color for fill the rectangle
1698 * ETO_CLIPPED - clipping text to the rectangle
1699 * ETO_GLYPH_INDEX - Buffer is of glyph locations in fonts rather
1700 * than encoded characters. Implies ETO_IGNORELANGUAGE
1701 * ETO_RTLREADING - Paragraph is basically a right-to-left paragraph.
1702 * Affects BiDi ordering
1703 * ETO_IGNORELANGUAGE - Undocumented in MSDN - instructs ExtTextOut not to do BiDi reordering
1704 * ETO_PDY - unimplemented
1705 * ETO_NUMERICSLATIN - unimplemented always assumed -
1706 * do not translate numbers into locale representations
1707 * ETO_NUMERICSLOCAL - unimplemented - Numerals in Arabic/Farsi context should assume local form
1708 * lprect [I] dimensions for clipping or/and opaquing
1709 * str [I] text string
1710 * count [I] number of symbols in string
1711 * lpDx [I] optional parameter with distance between drawing characters
1717 BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
1718 const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx )
1721 DC * dc = DC_GetDCUpdate( hdc );
1724 if (flags&(ETO_NUMERICSLOCAL|ETO_NUMERICSLATIN|ETO_PDY))
1725 FIXME("flags ETO_NUMERICSLOCAL|ETO_NUMERICSLATIN|ETO_PDY unimplemented\n");
1727 if(PATH_IsPathOpen(dc->path))
1728 FIXME("called on an open path\n");
1729 else if(dc->funcs->pExtTextOut)
1731 if( !(flags&(ETO_GLYPH_INDEX|ETO_IGNORELANGUAGE)) && BidiAvail && count>0 )
1733 /* The caller did not specify that language processing was already done.
1735 LPWSTR lpReorderedString=HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
1737 BIDI_Reorder( str, count, GCP_REORDER,
1738 ((flags&ETO_RTLREADING)!=0 || (GetTextAlign(hdc)&TA_RTLREADING)!=0)?
1739 WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR,
1740 lpReorderedString, count, NULL );
1742 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags|ETO_IGNORELANGUAGE,
1743 lprect,lpReorderedString,count,lpDx,dc->breakExtra);
1744 HeapFree(GetProcessHeap(), 0, lpReorderedString);
1746 ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,
1747 lpDx,dc->breakExtra);
1749 GDI_ReleaseObj( hdc );
1755 /***********************************************************************
1756 * TextOutA (GDI32.@)
1758 BOOL WINAPI TextOutA( HDC hdc, INT x, INT y, LPCSTR str, INT count )
1760 return ExtTextOutA( hdc, x, y, 0, NULL, str, count, NULL );
1764 /***********************************************************************
1765 * TextOutW (GDI32.@)
1767 BOOL WINAPI TextOutW(HDC hdc, INT x, INT y, LPCWSTR str, INT count)
1769 return ExtTextOutW( hdc, x, y, 0, NULL, str, count, NULL );
1773 /***********************************************************************
1774 * PolyTextOutA (GDI32.@)
1776 * Draw several Strings
1778 BOOL WINAPI PolyTextOutA ( HDC hdc, /* [in] Handle to device context */
1779 PPOLYTEXTA pptxt, /* [in] Array of strings */
1780 INT cStrings ) /* [in] Number of strings in array */
1782 for (; cStrings>0; cStrings--, pptxt++)
1783 if (!ExtTextOutA( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
1790 /***********************************************************************
1791 * PolyTextOutW (GDI32.@)
1793 * Draw several Strings
1795 BOOL WINAPI PolyTextOutW ( HDC hdc, /* [in] Handle to device context */
1796 PPOLYTEXTW pptxt, /* [in] Array of strings */
1797 INT cStrings ) /* [in] Number of strings in array */
1799 for (; cStrings>0; cStrings--, pptxt++)
1800 if (!ExtTextOutW( hdc, pptxt->x, pptxt->y, pptxt->uiFlags, &pptxt->rcl, pptxt->lpstr, pptxt->n, pptxt->pdx ))
1806 /* FIXME: all following APIs ******************************************/
1809 /***********************************************************************
1810 * SetMapperFlags (GDI32.@)
1812 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1814 DC *dc = DC_GetDCPtr( hDC );
1817 if(dc->funcs->pSetMapperFlags)
1818 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1820 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1821 GDI_ReleaseObj( hDC );
1825 /***********************************************************************
1826 * GetAspectRatioFilterEx (GDI.486)
1828 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1830 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1834 /***********************************************************************
1835 * GetAspectRatioFilterEx (GDI32.@)
1837 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1839 FIXME("(%p, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1844 /***********************************************************************
1845 * GetCharABCWidthsA (GDI32.@)
1847 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1850 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1855 if(count <= 0) return FALSE;
1857 str = HeapAlloc(GetProcessHeap(), 0, count);
1858 for(i = 0; i < count; i++)
1859 str[i] = (BYTE)(firstChar + i);
1861 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1863 for(i = 0; i < wlen; i++)
1865 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1873 HeapFree(GetProcessHeap(), 0, str);
1874 HeapFree(GetProcessHeap(), 0, wstr);
1880 /******************************************************************************
1881 * GetCharABCWidthsW [GDI32.@]
1883 * Retrieves widths of characters in range.
1886 * hdc [I] Handle of device context
1887 * firstChar [I] First character in range to query
1888 * lastChar [I] Last character in range to query
1889 * abc [O] Address of character-width structure
1892 * Only works with TrueType fonts
1898 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1901 DC *dc = DC_GetDCPtr(hdc);
1906 ret = WineEngGetCharABCWidths( dc->gdiFont, firstChar, lastChar, abc );
1912 /* convert device units to logical */
1913 for( i = firstChar; i <= lastChar; i++, abc++ ) {
1914 abc->abcA = INTERNAL_XDSTOWS(dc, abc->abcA);
1915 abc->abcB = INTERNAL_XDSTOWS(dc, abc->abcB);
1916 abc->abcC = INTERNAL_XDSTOWS(dc, abc->abcC);
1921 GDI_ReleaseObj(hdc);
1926 /***********************************************************************
1927 * GetGlyphOutlineA (GDI32.@)
1929 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1930 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1931 LPVOID lpBuffer, const MAT2 *lpmat2 )
1937 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1940 if(uChar > 0xff) { /* but, 2 bytes character only */
1942 mbchs[0] = (uChar & 0xff00) >> 8;
1943 mbchs[1] = (uChar & 0xff);
1946 mbchs[0] = (uChar & 0xff);
1948 p = FONT_mbtowc(hdc, mbchs, len, NULL, NULL);
1952 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1954 HeapFree(GetProcessHeap(), 0, p);
1958 /***********************************************************************
1959 * GetGlyphOutlineW (GDI32.@)
1961 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1962 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1963 LPVOID lpBuffer, const MAT2 *lpmat2 )
1965 DC *dc = DC_GetDCPtr(hdc);
1968 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1969 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1971 if(!dc) return GDI_ERROR;
1974 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1975 cbBuffer, lpBuffer, lpmat2);
1979 GDI_ReleaseObj(hdc);
1984 /***********************************************************************
1985 * CreateScalableFontResourceA (GDI32.@)
1987 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1988 LPCSTR lpszResourceFile,
1989 LPCSTR lpszFontFile,
1990 LPCSTR lpszCurrentPath )
1994 /* fHidden=1 - only visible for the calling app, read-only, not
1995 * enumbered with EnumFonts/EnumFontFamilies
1996 * lpszCurrentPath can be NULL
1998 FIXME("(%ld,%s,%s,%s): stub\n",
1999 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
2000 debugstr_a(lpszCurrentPath) );
2002 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
2003 if ((f = CreateFileA(lpszResourceFile, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) != INVALID_HANDLE_VALUE) {
2005 SetLastError(ERROR_FILE_EXISTS);
2008 return FALSE; /* create failed */
2011 /***********************************************************************
2012 * CreateScalableFontResourceW (GDI32.@)
2014 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
2015 LPCWSTR lpszResourceFile,
2016 LPCWSTR lpszFontFile,
2017 LPCWSTR lpszCurrentPath )
2019 FIXME("(%ld,%p,%p,%p): stub\n",
2020 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
2021 return FALSE; /* create failed */
2025 /*************************************************************************
2026 * GetRasterizerCaps (GDI32.@)
2028 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
2030 lprs->nSize = sizeof(RASTERIZER_STATUS);
2031 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
2032 lprs->nLanguageID = 0;
2037 /*************************************************************************
2038 * GetKerningPairsA (GDI32.@)
2040 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2041 LPKERNINGPAIR lpKerningPairs )
2043 return GetKerningPairsW( hDC, cPairs, lpKerningPairs );
2047 /*************************************************************************
2048 * GetKerningPairsW (GDI32.@)
2050 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2051 LPKERNINGPAIR lpKerningPairs )
2054 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2055 for (i = 0; i < cPairs; i++)
2056 lpKerningPairs[i].iKernAmount = 0;
2060 /*************************************************************************
2061 * TranslateCharsetInfo [GDI32.@]
2063 * Fills a CHARSETINFO structure for a character set, code page, or
2064 * font. This allows making the correspondance between different labelings
2065 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2066 * of the same encoding.
2068 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2069 * only one codepage should be set in *lpSrc.
2072 * TRUE on success, FALSE on failure.
2075 BOOL WINAPI TranslateCharsetInfo(
2076 LPDWORD lpSrc, /* [in]
2077 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2078 if flags == TCI_SRCCHARSET: a character set value
2079 if flags == TCI_SRCCODEPAGE: a code page value
2081 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2082 DWORD flags /* [in] determines interpretation of lpSrc */)
2086 case TCI_SRCFONTSIG:
2087 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2089 case TCI_SRCCODEPAGE:
2090 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2092 case TCI_SRCCHARSET:
2093 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2098 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2099 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2103 /*************************************************************************
2104 * GetFontLanguageInfo (GDI32.@)
2106 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
2108 FONTSIGNATURE fontsig;
2109 static const DWORD GCP_DBCS_MASK=0x003F0000,
2110 GCP_DIACRITIC_MASK=0x00000000,
2111 FLI_GLYPHS_MASK=0x00000000,
2112 GCP_GLYPHSHAPE_MASK=0x00000040,
2113 GCP_KASHIDA_MASK=0x00000000,
2114 GCP_LIGATE_MASK=0x00000000,
2115 GCP_USEKERNING_MASK=0x00000000,
2116 GCP_REORDER_MASK=0x00000060;
2120 GetTextCharsetInfo( hdc, &fontsig, 0 );
2121 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
2123 if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
2126 if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
2127 result|=GCP_DIACRITIC;
2129 if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
2132 if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
2133 result|=GCP_GLYPHSHAPE;
2135 if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
2136 result|=GCP_KASHIDA;
2138 if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
2141 if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
2142 result|=GCP_USEKERNING;
2144 /* this might need a test for a HEBREW- or ARABIC_CHARSET as well */
2145 if( GetTextAlign( hdc) & TA_RTLREADING )
2146 if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
2147 result|=GCP_REORDER;
2153 /*************************************************************************
2154 * GetFontData [GDI32.@]
2156 * Retrieve data for TrueType font.
2160 * success: Number of bytes returned
2161 * failure: GDI_ERROR
2165 * Calls SetLastError()
2168 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2169 LPVOID buffer, DWORD length)
2171 DC *dc = DC_GetDCPtr(hdc);
2172 DWORD ret = GDI_ERROR;
2174 if(!dc) return GDI_ERROR;
2177 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2179 GDI_ReleaseObj(hdc);
2183 /*************************************************************************
2184 * GetGlyphIndicesA [GDI32.@]
2186 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2187 LPWORD pgi, DWORD flags)
2193 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
2194 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2196 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2197 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2198 HeapFree(GetProcessHeap(), 0, lpstrW);
2203 /*************************************************************************
2204 * GetGlyphIndicesW [GDI32.@]
2206 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2207 LPWORD pgi, DWORD flags)
2209 DC *dc = DC_GetDCPtr(hdc);
2210 DWORD ret = GDI_ERROR;
2212 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
2213 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2215 if(!dc) return GDI_ERROR;
2218 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2220 GDI_ReleaseObj(hdc);
2224 /*************************************************************************
2225 * GetCharacterPlacementA [GDI32.@]
2228 * the web browser control of ie4 calls this with dwFlags=0
2231 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2232 INT nMaxExtent, GCP_RESULTSA *lpResults,
2237 GCP_RESULTSW resultsW;
2241 TRACE("%s, %d, %d, 0x%08lx\n",
2242 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2244 /* both structs are equal in size */
2245 memcpy(&resultsW, lpResults, sizeof(resultsW));
2247 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2248 if(lpResults->lpOutString)
2249 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
2251 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2253 if(lpResults->lpOutString) {
2254 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2255 lpResults->lpOutString, uCount, NULL, NULL );
2258 HeapFree(GetProcessHeap(), 0, lpStringW);
2259 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2264 /*************************************************************************
2265 * GetCharacterPlacementW [GDI32.@]
2267 * Retrieve information about a string. This includes the width, reordering,
2268 * Glyphing and so on.
2272 * The width and height of the string if successful, 0 if failed.
2276 * All flags except GCP_REORDER are not yet implemented.
2277 * Reordering is not 100% complient to the Windows BiDi method.
2278 * Caret positioning is not yet implemented for BiDi.
2279 * Classes are not yet implemented.
2283 GetCharacterPlacementW(
2284 HDC hdc, /* [in] Device context for which the rendering is to be done */
2285 LPCWSTR lpString, /* [in] The string for which information is to be returned */
2286 INT uCount, /* [in] Number of WORDS in string. */
2287 INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
2288 GCP_RESULTSW *lpResults,/* [in/out] A pointer to a GCP_RESULTSW struct */
2289 DWORD dwFlags /* [in] Flags specifying how to process the string */
2296 TRACE("%s, %d, %d, 0x%08lx\n",
2297 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2299 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2300 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2301 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2302 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2303 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2305 if(dwFlags&(~GCP_REORDER)) FIXME("flags 0x%08lx ignored\n", dwFlags);
2306 if(lpResults->lpClass) FIXME("classes not implemented\n");
2307 if (lpResults->lpCaretPos && (dwFlags & GCP_REORDER))
2308 FIXME("Caret positions for complex scripts not implemented\n");
2310 nSet = (UINT)uCount;
2311 if(nSet > lpResults->nGlyphs)
2312 nSet = lpResults->nGlyphs;
2314 /* return number of initialized fields */
2315 lpResults->nGlyphs = nSet;
2317 if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
2319 /* Treat the case where no special handling was requested in a fastpath way */
2320 /* copy will do if the GCP_REORDER flag is not set */
2321 if(lpResults->lpOutString)
2322 memcpy( lpResults->lpOutString, lpString, nSet * sizeof(WCHAR));
2324 if(lpResults->lpOrder)
2326 for(i = 0; i < nSet; i++)
2327 lpResults->lpOrder[i] = i;
2331 BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
2332 nSet, lpResults->lpOrder );
2335 /* FIXME: Will use the placement chars */
2336 if (lpResults->lpDx)
2339 for (i = 0; i < nSet; i++)
2341 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2342 lpResults->lpDx[i]= c;
2346 if (lpResults->lpCaretPos && !(dwFlags & GCP_REORDER))
2350 lpResults->lpCaretPos[0] = 0;
2351 for (i = 1; i < nSet; i++)
2352 if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
2353 lpResults->lpCaretPos[i] = (pos += size.cx);
2356 if(lpResults->lpGlyphs)
2357 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2359 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2360 ret = MAKELONG(size.cx, size.cy);
2365 /*************************************************************************
2366 * GetCharABCWidthsFloatA [GDI32.@]
2368 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2371 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2375 /*************************************************************************
2376 * GetCharABCWidthsFloatW [GDI32.@]
2378 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2379 UINT iLastChar, LPABCFLOAT lpABCF)
2381 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2385 /*************************************************************************
2386 * GetCharWidthFloatA [GDI32.@]
2388 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2389 UINT iLastChar, PFLOAT pxBuffer)
2391 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2395 /*************************************************************************
2396 * GetCharWidthFloatW [GDI32.@]
2398 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2399 UINT iLastChar, PFLOAT pxBuffer)
2401 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2406 /***********************************************************************
2408 * Font Resource API *
2410 ***********************************************************************/
2412 /***********************************************************************
2413 * AddFontResourceA (GDI32.@)
2415 INT WINAPI AddFontResourceA( LPCSTR str )
2417 return AddFontResourceExA( str, 0, NULL);
2420 /***********************************************************************
2421 * AddFontResourceW (GDI32.@)
2423 INT WINAPI AddFontResourceW( LPCWSTR str )
2425 return AddFontResourceExW(str, 0, NULL);
2429 /***********************************************************************
2430 * AddFontResourceExA (GDI32.@)
2432 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2434 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2435 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2438 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2439 ret = AddFontResourceExW(strW, fl, pdv);
2440 HeapFree(GetProcessHeap(), 0, strW);
2444 /***********************************************************************
2445 * AddFontResourceExW (GDI32.@)
2447 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2449 return WineEngAddFontResourceEx(str, fl, pdv);
2452 /***********************************************************************
2453 * RemoveFontResourceA (GDI32.@)
2455 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2457 return RemoveFontResourceExA(str, 0, 0);
2460 /***********************************************************************
2461 * RemoveFontResourceW (GDI32.@)
2463 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2465 return RemoveFontResourceExW(str, 0, 0);
2468 /***********************************************************************
2469 * RemoveFontResourceExA (GDI32.@)
2471 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2473 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2474 LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2477 MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2478 ret = RemoveFontResourceExW(strW, fl, pdv);
2479 HeapFree(GetProcessHeap(), 0, strW);
2483 /***********************************************************************
2484 * RemoveFontResourceExW (GDI32.@)
2486 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2488 return WineEngRemoveFontResourceEx(str, fl, pdv);
2491 /***********************************************************************
2492 * GetTextCharset (GDI32.@)
2494 UINT WINAPI GetTextCharset(HDC hdc)
2496 /* MSDN docs say this is equivalent */
2497 return GetTextCharsetInfo(hdc, NULL, 0);
2500 /***********************************************************************
2501 * GetTextCharsetInfo (GDI32.@)
2503 UINT WINAPI GetTextCharsetInfo(HDC hdc, LPFONTSIGNATURE fs, DWORD flags)
2505 UINT ret = DEFAULT_CHARSET;
2506 DC *dc = DC_GetDCPtr(hdc);
2511 ret = WineEngGetTextCharsetInfo(dc->gdiFont, fs, flags);
2513 GDI_ReleaseObj(hdc);
2516 if (ret == DEFAULT_CHARSET && fs)
2517 memset(fs, 0, sizeof(FONTSIGNATURE));