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
);
71 static inline INT
INTERNAL_XWSTODS(DC
*dc
, INT width
)
74 pt
[0].x
= pt
[0].y
= 0;
77 LPtoDP(dc
->hSelf
, pt
, 2);
78 return pt
[1].x
- pt
[0].x
;
81 static inline INT
INTERNAL_YWSTODS(DC
*dc
, INT height
)
84 pt
[0].x
= pt
[0].y
= 0;
87 LPtoDP(dc
->hSelf
, pt
, 2);
88 return pt
[1].y
- pt
[0].y
;
91 static HGDIOBJ
FONT_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
);
92 static INT
FONT_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
93 static INT
FONT_GetObjectA( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
94 static INT
FONT_GetObjectW( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
95 static BOOL
FONT_DeleteObject( HGDIOBJ handle
, void *obj
);
97 static const struct gdi_obj_funcs font_funcs
=
99 FONT_SelectObject
, /* pSelectObject */
100 FONT_GetObject16
, /* pGetObject16 */
101 FONT_GetObjectA
, /* pGetObjectA */
102 FONT_GetObjectW
, /* pGetObjectW */
103 NULL
, /* pUnrealizeObject */
104 FONT_DeleteObject
/* pDeleteObject */
107 #define ENUM_UNICODE 0x00000001
108 #define ENUM_CALLED 0x00000002
118 LPLOGFONT16 lpLogFontParam
;
119 FONTENUMPROC16 lpEnumFunc
;
122 LPNEWTEXTMETRICEX16 lpTextMetric
;
123 LPENUMLOGFONTEX16 lpLogFont
;
124 SEGPTR segTextMetric
;
134 LPLOGFONTW lpLogFontParam
;
135 FONTENUMPROCW lpEnumFunc
;
144 * For TranslateCharsetInfo
146 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
147 #define MAXTCIINDEX 32
148 static const CHARSETINFO FONT_tci
[MAXTCIINDEX
] = {
150 { ANSI_CHARSET
, 1252, FS(0)},
151 { EASTEUROPE_CHARSET
, 1250, FS(1)},
152 { RUSSIAN_CHARSET
, 1251, FS(2)},
153 { GREEK_CHARSET
, 1253, FS(3)},
154 { TURKISH_CHARSET
, 1254, FS(4)},
155 { HEBREW_CHARSET
, 1255, FS(5)},
156 { ARABIC_CHARSET
, 1256, FS(6)},
157 { BALTIC_CHARSET
, 1257, FS(7)},
158 { VIETNAMESE_CHARSET
, 1258, FS(8)},
159 /* reserved by ANSI */
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 { DEFAULT_CHARSET
, 0, FS(0)},
165 { DEFAULT_CHARSET
, 0, FS(0)},
166 { DEFAULT_CHARSET
, 0, FS(0)},
168 { THAI_CHARSET
, 874, FS(16)},
169 { SHIFTJIS_CHARSET
, 932, FS(17)},
170 { GB2312_CHARSET
, 936, FS(18)},
171 { HANGEUL_CHARSET
, 949, FS(19)},
172 { CHINESEBIG5_CHARSET
, 950, FS(20)},
173 { JOHAB_CHARSET
, 1361, FS(21)},
174 /* reserved for alternate ANSI and OEM */
175 { DEFAULT_CHARSET
, 0, FS(0)},
176 { DEFAULT_CHARSET
, 0, FS(0)},
177 { DEFAULT_CHARSET
, 0, FS(0)},
178 { DEFAULT_CHARSET
, 0, FS(0)},
179 { DEFAULT_CHARSET
, 0, FS(0)},
180 { DEFAULT_CHARSET
, 0, FS(0)},
181 { DEFAULT_CHARSET
, 0, FS(0)},
182 { DEFAULT_CHARSET
, 0, FS(0)},
183 /* reserved for system */
184 { DEFAULT_CHARSET
, 0, FS(0)},
185 { SYMBOL_CHARSET
, CP_SYMBOL
, FS(31)},
188 /***********************************************************************
189 * LOGFONT conversion functions.
191 static void FONT_LogFontWTo16( const LOGFONTW
* font32
, LPLOGFONT16 font16
)
193 font16
->lfHeight
= font32
->lfHeight
;
194 font16
->lfWidth
= font32
->lfWidth
;
195 font16
->lfEscapement
= font32
->lfEscapement
;
196 font16
->lfOrientation
= font32
->lfOrientation
;
197 font16
->lfWeight
= font32
->lfWeight
;
198 font16
->lfItalic
= font32
->lfItalic
;
199 font16
->lfUnderline
= font32
->lfUnderline
;
200 font16
->lfStrikeOut
= font32
->lfStrikeOut
;
201 font16
->lfCharSet
= font32
->lfCharSet
;
202 font16
->lfOutPrecision
= font32
->lfOutPrecision
;
203 font16
->lfClipPrecision
= font32
->lfClipPrecision
;
204 font16
->lfQuality
= font32
->lfQuality
;
205 font16
->lfPitchAndFamily
= font32
->lfPitchAndFamily
;
206 WideCharToMultiByte( CP_ACP
, 0, font32
->lfFaceName
, -1,
207 font16
->lfFaceName
, LF_FACESIZE
, NULL
, NULL
);
208 font16
->lfFaceName
[LF_FACESIZE
-1] = 0;
211 static void FONT_LogFont16ToW( const LOGFONT16
*font16
, LPLOGFONTW font32
)
213 font32
->lfHeight
= font16
->lfHeight
;
214 font32
->lfWidth
= font16
->lfWidth
;
215 font32
->lfEscapement
= font16
->lfEscapement
;
216 font32
->lfOrientation
= font16
->lfOrientation
;
217 font32
->lfWeight
= font16
->lfWeight
;
218 font32
->lfItalic
= font16
->lfItalic
;
219 font32
->lfUnderline
= font16
->lfUnderline
;
220 font32
->lfStrikeOut
= font16
->lfStrikeOut
;
221 font32
->lfCharSet
= font16
->lfCharSet
;
222 font32
->lfOutPrecision
= font16
->lfOutPrecision
;
223 font32
->lfClipPrecision
= font16
->lfClipPrecision
;
224 font32
->lfQuality
= font16
->lfQuality
;
225 font32
->lfPitchAndFamily
= font16
->lfPitchAndFamily
;
226 MultiByteToWideChar( CP_ACP
, 0, font16
->lfFaceName
, -1, font32
->lfFaceName
, LF_FACESIZE
);
227 font32
->lfFaceName
[LF_FACESIZE
-1] = 0;
230 static void FONT_LogFontAToW( const LOGFONTA
*fontA
, LPLOGFONTW fontW
)
232 memcpy(fontW
, fontA
, sizeof(LOGFONTA
) - LF_FACESIZE
);
233 MultiByteToWideChar(CP_ACP
, 0, fontA
->lfFaceName
, -1, fontW
->lfFaceName
,
235 fontW
->lfFaceName
[LF_FACESIZE
-1] = 0;
238 static void FONT_LogFontWToA( const LOGFONTW
*fontW
, LPLOGFONTA fontA
)
240 memcpy(fontA
, fontW
, sizeof(LOGFONTA
) - LF_FACESIZE
);
241 WideCharToMultiByte(CP_ACP
, 0, fontW
->lfFaceName
, -1, fontA
->lfFaceName
,
242 LF_FACESIZE
, NULL
, NULL
);
243 fontA
->lfFaceName
[LF_FACESIZE
-1] = 0;
246 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW
*fontW
, LPENUMLOGFONTEX16 font16
)
248 FONT_LogFontWTo16( (LPLOGFONTW
)fontW
, (LPLOGFONT16
)font16
);
250 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfFullName
, -1,
251 (LPSTR
) font16
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
252 font16
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
253 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfStyle
, -1,
254 (LPSTR
) font16
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
255 font16
->elfStyle
[LF_FACESIZE
-1] = '\0';
256 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfScript
, -1,
257 (LPSTR
) font16
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
258 font16
->elfScript
[LF_FACESIZE
-1] = '\0';
261 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW
*fontW
, LPENUMLOGFONTEXA fontA
)
263 FONT_LogFontWToA( (LPLOGFONTW
)fontW
, (LPLOGFONTA
)fontA
);
265 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfFullName
, -1,
266 (LPSTR
) fontA
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
267 fontA
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
268 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfStyle
, -1,
269 (LPSTR
) fontA
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
270 fontA
->elfStyle
[LF_FACESIZE
-1] = '\0';
271 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfScript
, -1,
272 (LPSTR
) fontA
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
273 fontA
->elfScript
[LF_FACESIZE
-1] = '\0';
276 /***********************************************************************
277 * TEXTMETRIC conversion functions.
279 static void FONT_TextMetricWToA(const TEXTMETRICW
*ptmW
, LPTEXTMETRICA ptmA
)
281 ptmA
->tmHeight
= ptmW
->tmHeight
;
282 ptmA
->tmAscent
= ptmW
->tmAscent
;
283 ptmA
->tmDescent
= ptmW
->tmDescent
;
284 ptmA
->tmInternalLeading
= ptmW
->tmInternalLeading
;
285 ptmA
->tmExternalLeading
= ptmW
->tmExternalLeading
;
286 ptmA
->tmAveCharWidth
= ptmW
->tmAveCharWidth
;
287 ptmA
->tmMaxCharWidth
= ptmW
->tmMaxCharWidth
;
288 ptmA
->tmWeight
= ptmW
->tmWeight
;
289 ptmA
->tmOverhang
= ptmW
->tmOverhang
;
290 ptmA
->tmDigitizedAspectX
= ptmW
->tmDigitizedAspectX
;
291 ptmA
->tmDigitizedAspectY
= ptmW
->tmDigitizedAspectY
;
292 ptmA
->tmFirstChar
= ptmW
->tmFirstChar
> 255 ? 255 : ptmW
->tmFirstChar
;
293 ptmA
->tmLastChar
= ptmW
->tmLastChar
> 255 ? 255 : ptmW
->tmLastChar
;
294 ptmA
->tmDefaultChar
= ptmW
->tmDefaultChar
> 255 ? 255 : ptmW
->tmDefaultChar
;
295 ptmA
->tmBreakChar
= ptmW
->tmBreakChar
> 255 ? 255 : ptmW
->tmBreakChar
;
296 ptmA
->tmItalic
= ptmW
->tmItalic
;
297 ptmA
->tmUnderlined
= ptmW
->tmUnderlined
;
298 ptmA
->tmStruckOut
= ptmW
->tmStruckOut
;
299 ptmA
->tmPitchAndFamily
= ptmW
->tmPitchAndFamily
;
300 ptmA
->tmCharSet
= ptmW
->tmCharSet
;
304 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW
*ptmW
, LPNEWTEXTMETRICEX16 ptm16
)
306 ptm16
->ntmTm
.tmHeight
= ptmW
->ntmTm
.tmHeight
;
307 ptm16
->ntmTm
.tmAscent
= ptmW
->ntmTm
.tmAscent
;
308 ptm16
->ntmTm
.tmDescent
= ptmW
->ntmTm
.tmDescent
;
309 ptm16
->ntmTm
.tmInternalLeading
= ptmW
->ntmTm
.tmInternalLeading
;
310 ptm16
->ntmTm
.tmExternalLeading
= ptmW
->ntmTm
.tmExternalLeading
;
311 ptm16
->ntmTm
.tmAveCharWidth
= ptmW
->ntmTm
.tmAveCharWidth
;
312 ptm16
->ntmTm
.tmMaxCharWidth
= ptmW
->ntmTm
.tmMaxCharWidth
;
313 ptm16
->ntmTm
.tmWeight
= ptmW
->ntmTm
.tmWeight
;
314 ptm16
->ntmTm
.tmOverhang
= ptmW
->ntmTm
.tmOverhang
;
315 ptm16
->ntmTm
.tmDigitizedAspectX
= ptmW
->ntmTm
.tmDigitizedAspectX
;
316 ptm16
->ntmTm
.tmDigitizedAspectY
= ptmW
->ntmTm
.tmDigitizedAspectY
;
317 ptm16
->ntmTm
.tmFirstChar
= ptmW
->ntmTm
.tmFirstChar
> 255 ? 255 : ptmW
->ntmTm
.tmFirstChar
;
318 ptm16
->ntmTm
.tmLastChar
= ptmW
->ntmTm
.tmLastChar
> 255 ? 255 : ptmW
->ntmTm
.tmLastChar
;
319 ptm16
->ntmTm
.tmDefaultChar
= ptmW
->ntmTm
.tmDefaultChar
> 255 ? 255 : ptmW
->ntmTm
.tmDefaultChar
;
320 ptm16
->ntmTm
.tmBreakChar
= ptmW
->ntmTm
.tmBreakChar
> 255 ? 255 : ptmW
->ntmTm
.tmBreakChar
;
321 ptm16
->ntmTm
.tmItalic
= ptmW
->ntmTm
.tmItalic
;
322 ptm16
->ntmTm
.tmUnderlined
= ptmW
->ntmTm
.tmUnderlined
;
323 ptm16
->ntmTm
.tmStruckOut
= ptmW
->ntmTm
.tmStruckOut
;
324 ptm16
->ntmTm
.tmPitchAndFamily
= ptmW
->ntmTm
.tmPitchAndFamily
;
325 ptm16
->ntmTm
.tmCharSet
= ptmW
->ntmTm
.tmCharSet
;
326 ptm16
->ntmTm
.ntmFlags
= ptmW
->ntmTm
.ntmFlags
;
327 ptm16
->ntmTm
.ntmSizeEM
= ptmW
->ntmTm
.ntmSizeEM
;
328 ptm16
->ntmTm
.ntmCellHeight
= ptmW
->ntmTm
.ntmCellHeight
;
329 ptm16
->ntmTm
.ntmAvgWidth
= ptmW
->ntmTm
.ntmAvgWidth
;
330 memcpy(&ptm16
->ntmFontSig
, &ptmW
->ntmFontSig
, sizeof(FONTSIGNATURE
));
333 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW
*ptmW
, NEWTEXTMETRICEXA
*ptmA
)
335 FONT_TextMetricWToA((LPTEXTMETRICW
)ptmW
, (LPTEXTMETRICA
)ptmA
);
336 ptmA
->ntmTm
.ntmFlags
= ptmW
->ntmTm
.ntmFlags
;
337 ptmA
->ntmTm
.ntmSizeEM
= ptmW
->ntmTm
.ntmSizeEM
;
338 ptmA
->ntmTm
.ntmCellHeight
= ptmW
->ntmTm
.ntmCellHeight
;
339 ptmA
->ntmTm
.ntmAvgWidth
= ptmW
->ntmTm
.ntmAvgWidth
;
340 memcpy(&ptmA
->ntmFontSig
, &ptmW
->ntmFontSig
, sizeof(FONTSIGNATURE
));
344 /***********************************************************************
347 * Returns a '\0' terminated Unicode translation of str using the
348 * charset of the currently selected font in hdc. If count is -1 then
349 * str is assumed to be '\0' terminated, otherwise it contains the
350 * number of bytes to convert. If plenW is non-NULL, on return it
351 * will point to the number of WCHARs (excluding the '\0') that have
352 * been written. If pCP is non-NULL, on return it will point to the
353 * codepage used in the conversion.
354 * The caller should free the returned LPWSTR from the process
357 static LPWSTR
FONT_mbtowc(HDC hdc
, LPCSTR str
, INT count
, INT
*plenW
, UINT
*pCP
)
363 int charset
= GetTextCharset(hdc
);
365 /* Hmm, nicely designed api this one! */
366 if(TranslateCharsetInfo((DWORD
*)charset
, &csi
, TCI_SRCCHARSET
))
373 case DEFAULT_CHARSET
:
384 /* FIXME: These have no place here, but because x11drv
385 enumerates fonts with these (made up) charsets some apps
386 might use them and then the FIXME below would become
387 annoying. Now we could pick the intended codepage for
388 each of these, but since it's broken anyway we'll just
389 use CP_ACP and hope it'll go away...
395 FIXME("Can't find codepage for charset %d\n", charset
);
400 TRACE("charset %d => cp %d\n", charset
, cp
);
402 if(count
== -1) count
= strlen(str
);
403 lenW
= MultiByteToWideChar(cp
, 0, str
, count
, NULL
, 0);
404 strW
= HeapAlloc(GetProcessHeap(), 0, (lenW
+ 1) * sizeof(WCHAR
));
405 MultiByteToWideChar(cp
, 0, str
, count
, strW
, lenW
);
407 TRACE("mapped %s -> %s\n", debugstr_an(str
, count
), debugstr_wn(strW
, lenW
));
408 if(plenW
) *plenW
= lenW
;
414 /***********************************************************************
415 * CreateFontIndirectA (GDI32.@)
417 HFONT WINAPI
CreateFontIndirectA( const LOGFONTA
*plfA
)
422 FONT_LogFontAToW( plfA
, &lfW
);
423 return CreateFontIndirectW( &lfW
);
425 return CreateFontIndirectW( NULL
);
429 /***********************************************************************
430 * CreateFontIndirectW (GDI32.@)
432 HFONT WINAPI
CreateFontIndirectW( const LOGFONTW
*plf
)
439 if ((fontPtr
= GDI_AllocObject( sizeof(FONTOBJ
), FONT_MAGIC
,
440 (HGDIOBJ
*)&hFont
, &font_funcs
)))
442 static const WCHAR ItalicW
[] = {' ','I','t','a','l','i','c','\0'};
443 static const WCHAR BoldW
[] = {' ','B','o','l','d','\0'};
444 WCHAR
*pFaceNameItalicSuffix
, *pFaceNameBoldSuffix
;
445 WCHAR
* pFaceNameSuffix
= NULL
;
447 memcpy( &fontPtr
->logfont
, plf
, sizeof(LOGFONTW
) );
449 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s %s => %p\n",
450 plf
->lfHeight
, plf
->lfWidth
,
451 plf
->lfEscapement
, plf
->lfOrientation
,
452 plf
->lfPitchAndFamily
,
453 plf
->lfOutPrecision
, plf
->lfClipPrecision
,
454 plf
->lfQuality
, plf
->lfCharSet
,
455 debugstr_w(plf
->lfFaceName
),
456 plf
->lfWeight
> 400 ? "Bold" : "",
457 plf
->lfItalic
? "Italic" : "",
458 plf
->lfUnderline
? "Underline" : "", hFont
);
460 if (plf
->lfEscapement
!= plf
->lfOrientation
) {
461 /* this should really depend on whether GM_ADVANCED is set */
462 fontPtr
->logfont
.lfOrientation
= fontPtr
->logfont
.lfEscapement
;
463 WARN("orientation angle %f set to "
464 "escapement angle %f for new font %p\n",
465 plf
->lfOrientation
/10., plf
->lfEscapement
/10., hFont
);
468 pFaceNameItalicSuffix
= strstrW(fontPtr
->logfont
.lfFaceName
, ItalicW
);
469 if (pFaceNameItalicSuffix
) {
470 fontPtr
->logfont
.lfItalic
= TRUE
;
471 pFaceNameSuffix
= pFaceNameItalicSuffix
;
474 pFaceNameBoldSuffix
= strstrW(fontPtr
->logfont
.lfFaceName
, BoldW
);
475 if (pFaceNameBoldSuffix
) {
476 if (fontPtr
->logfont
.lfWeight
< FW_BOLD
) {
477 fontPtr
->logfont
.lfWeight
= FW_BOLD
;
479 if (!pFaceNameSuffix
||
480 (pFaceNameBoldSuffix
< pFaceNameSuffix
)) {
481 pFaceNameSuffix
= pFaceNameBoldSuffix
;
485 if (pFaceNameSuffix
) *pFaceNameSuffix
= 0;
487 GDI_ReleaseObj( hFont
);
490 else WARN("(NULL) => NULL\n");
495 /*************************************************************************
496 * CreateFontA (GDI32.@)
498 HFONT WINAPI
CreateFontA( INT height
, INT width
, INT esc
,
499 INT orient
, INT weight
, DWORD italic
,
500 DWORD underline
, DWORD strikeout
, DWORD charset
,
501 DWORD outpres
, DWORD clippres
, DWORD quality
,
502 DWORD pitch
, LPCSTR name
)
506 logfont
.lfHeight
= height
;
507 logfont
.lfWidth
= width
;
508 logfont
.lfEscapement
= esc
;
509 logfont
.lfOrientation
= orient
;
510 logfont
.lfWeight
= weight
;
511 logfont
.lfItalic
= italic
;
512 logfont
.lfUnderline
= underline
;
513 logfont
.lfStrikeOut
= strikeout
;
514 logfont
.lfCharSet
= charset
;
515 logfont
.lfOutPrecision
= outpres
;
516 logfont
.lfClipPrecision
= clippres
;
517 logfont
.lfQuality
= quality
;
518 logfont
.lfPitchAndFamily
= pitch
;
521 lstrcpynA(logfont
.lfFaceName
,name
,sizeof(logfont
.lfFaceName
));
523 logfont
.lfFaceName
[0] = '\0';
525 return CreateFontIndirectA( &logfont
);
528 /*************************************************************************
529 * CreateFontW (GDI32.@)
531 HFONT WINAPI
CreateFontW( INT height
, INT width
, INT esc
,
532 INT orient
, INT weight
, DWORD italic
,
533 DWORD underline
, DWORD strikeout
, DWORD charset
,
534 DWORD outpres
, DWORD clippres
, DWORD quality
,
535 DWORD pitch
, LPCWSTR name
)
539 logfont
.lfHeight
= height
;
540 logfont
.lfWidth
= width
;
541 logfont
.lfEscapement
= esc
;
542 logfont
.lfOrientation
= orient
;
543 logfont
.lfWeight
= weight
;
544 logfont
.lfItalic
= italic
;
545 logfont
.lfUnderline
= underline
;
546 logfont
.lfStrikeOut
= strikeout
;
547 logfont
.lfCharSet
= charset
;
548 logfont
.lfOutPrecision
= outpres
;
549 logfont
.lfClipPrecision
= clippres
;
550 logfont
.lfQuality
= quality
;
551 logfont
.lfPitchAndFamily
= pitch
;
554 lstrcpynW(logfont
.lfFaceName
, name
,
555 sizeof(logfont
.lfFaceName
) / sizeof(WCHAR
));
557 logfont
.lfFaceName
[0] = '\0';
559 return CreateFontIndirectW( &logfont
);
563 /***********************************************************************
566 * If the driver supports vector fonts we create a gdi font first and
567 * then call the driver to give it a chance to supply its own device
568 * font. If the driver wants to do this it returns TRUE and we can
569 * delete the gdi font, if the driver wants to use the gdi font it
570 * should return FALSE, to signal an error return GDI_ERROR. For
571 * drivers that don't support vector fonts they must supply their own
574 static HGDIOBJ
FONT_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
)
577 DC
*dc
= DC_GetDCPtr( hdc
);
581 if (dc
->hFont
!= handle
|| dc
->gdiFont
== NULL
)
583 if(GetDeviceCaps(dc
->hSelf
, TEXTCAPS
) & TC_VA_ABLE
)
584 dc
->gdiFont
= WineEngCreateFontInstance(dc
, handle
);
587 if (dc
->funcs
->pSelectFont
) ret
= dc
->funcs
->pSelectFont( dc
->physDev
, handle
, dc
->gdiFont
);
589 if (ret
&& dc
->gdiFont
) dc
->gdiFont
= 0;
591 if (ret
== HGDI_ERROR
)
592 ret
= 0; /* SelectObject returns 0 on error */
598 GDI_ReleaseObj( hdc
);
603 /***********************************************************************
606 static INT
FONT_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
611 FONT_LogFontWTo16( &font
->logfont
, &lf16
);
613 if (count
> sizeof(LOGFONT16
)) count
= sizeof(LOGFONT16
);
614 memcpy( buffer
, &lf16
, count
);
618 /***********************************************************************
621 static INT
FONT_GetObjectA( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
628 FONT_LogFontWToA( &font
->logfont
, &lfA
);
630 if (count
> sizeof(lfA
)) count
= sizeof(lfA
);
631 memcpy( buffer
, &lfA
, count
);
635 /***********************************************************************
638 static INT
FONT_GetObjectW( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
642 return sizeof(LOGFONTW
);
643 if (count
> sizeof(LOGFONTW
)) count
= sizeof(LOGFONTW
);
644 memcpy( buffer
, &font
->logfont
, count
);
649 /***********************************************************************
652 static BOOL
FONT_DeleteObject( HGDIOBJ handle
, void *obj
)
654 WineEngDestroyFontInstance( handle
);
655 return GDI_FreeObject( handle
, obj
);
659 /***********************************************************************
660 * FONT_EnumInstance16
662 * Called by the device driver layer to pass font info
663 * down to the application.
665 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
666 * We have to use other types because of the FONTENUMPROCW definition.
668 static INT CALLBACK
FONT_EnumInstance16( const LOGFONTW
*plf
, const TEXTMETRICW
*ptm
,
669 DWORD fType
, LPARAM lp
)
671 fontEnum16
*pfe
= (fontEnum16
*)lp
;
675 if( pfe
->lpLogFontParam
->lfCharSet
== DEFAULT_CHARSET
||
676 pfe
->lpLogFontParam
->lfCharSet
== plf
->lfCharSet
)
681 FONT_EnumLogFontExWTo16((const ENUMLOGFONTEXW
*)plf
, pfe
->lpLogFont
);
682 FONT_NewTextMetricExWTo16((const NEWTEXTMETRICEXW
*)ptm
, pfe
->lpTextMetric
);
683 pfe
->dwFlags
|= ENUM_CALLED
;
684 GDI_ReleaseObj( pfe
->hdc
); /* release the GDI lock */
686 args
[6] = SELECTOROF(pfe
->segLogFont
);
687 args
[5] = OFFSETOF(pfe
->segLogFont
);
688 args
[4] = SELECTOROF(pfe
->segTextMetric
);
689 args
[3] = OFFSETOF(pfe
->segTextMetric
);
691 args
[1] = HIWORD(pfe
->lpData
);
692 args
[0] = LOWORD(pfe
->lpData
);
693 WOWCallback16Ex( (DWORD
)pfe
->lpEnumFunc
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
694 ret
= LOWORD(result
);
696 /* get the lock again and make sure the DC is still valid */
697 dc
= DC_GetDCPtr( pfe
->hdc
);
698 if (!dc
|| dc
!= pfe
->dc
|| dc
->physDev
!= pfe
->physDev
)
700 if (dc
) GDI_ReleaseObj( pfe
->hdc
);
701 pfe
->hdc
= 0; /* make sure we don't try to release it later on */
708 /***********************************************************************
711 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
712 * We have to use other types because of the FONTENUMPROCW definition.
714 static INT CALLBACK
FONT_EnumInstance( const LOGFONTW
*plf
, const TEXTMETRICW
*ptm
,
715 DWORD fType
, LPARAM lp
)
717 fontEnum32
*pfe
= (fontEnum32
*)lp
;
721 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
722 if((pfe
->lpLogFontParam
->lfCharSet
== DEFAULT_CHARSET
||
723 pfe
->lpLogFontParam
->lfCharSet
== plf
->lfCharSet
) &&
724 (!(fType
& RASTER_FONTTYPE
) || GetDeviceCaps(pfe
->hdc
, TEXTCAPS
) & TC_RA_ABLE
) )
726 /* convert font metrics */
727 ENUMLOGFONTEXA logfont
;
728 NEWTEXTMETRICEXA tmA
;
730 pfe
->dwFlags
|= ENUM_CALLED
;
731 if (!(pfe
->dwFlags
& ENUM_UNICODE
))
733 FONT_EnumLogFontExWToA( (const ENUMLOGFONTEXW
*)plf
, &logfont
);
734 FONT_NewTextMetricExWToA( (const NEWTEXTMETRICEXW
*)ptm
, &tmA
);
735 plf
= (LOGFONTW
*)&logfont
.elfLogFont
;
736 ptm
= (TEXTMETRICW
*)&tmA
;
738 GDI_ReleaseObj( pfe
->hdc
); /* release the GDI lock */
740 ret
= pfe
->lpEnumFunc( plf
, ptm
, fType
, pfe
->lpData
);
742 /* get the lock again and make sure the DC is still valid */
743 dc
= DC_GetDCPtr( pfe
->hdc
);
744 if (!dc
|| dc
!= pfe
->dc
|| dc
->physDev
!= pfe
->physDev
)
746 if (dc
) GDI_ReleaseObj( pfe
->hdc
);
747 pfe
->hdc
= 0; /* make sure we don't try to release it later on */
754 /***********************************************************************
755 * EnumFontFamiliesEx (GDI.613)
757 INT16 WINAPI
EnumFontFamiliesEx16( HDC16 hDC
, LPLOGFONT16 plf
,
758 FONTENUMPROC16 efproc
, LPARAM lParam
,
763 DC
* dc
= DC_GetDCPtr( HDC_32(hDC
) );
764 NEWTEXTMETRICEX16 tm16
;
765 ENUMLOGFONTEX16 lf16
;
770 FONT_LogFont16ToW(plf
, &lfW
);
772 fe16
.hdc
= HDC_32(hDC
);
774 fe16
.physDev
= dc
->physDev
;
775 fe16
.lpLogFontParam
= plf
;
776 fe16
.lpEnumFunc
= efproc
;
777 fe16
.lpData
= lParam
;
778 fe16
.lpTextMetric
= &tm16
;
779 fe16
.lpLogFont
= &lf16
;
780 fe16
.segTextMetric
= MapLS( &tm16
);
781 fe16
.segLogFont
= MapLS( &lf16
);
784 enum_gdi_fonts
= GetDeviceCaps(fe16
.hdc
, TEXTCAPS
) & TC_VA_ABLE
;
786 if (!dc
->funcs
->pEnumDeviceFonts
&& !enum_gdi_fonts
)
793 ret
= WineEngEnumFonts( &lfW
, FONT_EnumInstance16
, (LPARAM
)&fe16
);
794 fe16
.dwFlags
&= ~ENUM_CALLED
;
795 if (ret
&& dc
->funcs
->pEnumDeviceFonts
) {
796 ret2
= dc
->funcs
->pEnumDeviceFonts( dc
->physDev
, &lfW
, FONT_EnumInstance16
, (LPARAM
)&fe16
);
797 if(fe16
.dwFlags
& ENUM_CALLED
) /* update ret iff a font gets enumed */
801 UnMapLS( fe16
.segTextMetric
);
802 UnMapLS( fe16
.segLogFont
);
803 if (fe16
.hdc
) GDI_ReleaseObj( fe16
.hdc
);
807 /***********************************************************************
808 * FONT_EnumFontFamiliesEx
810 static INT
FONT_EnumFontFamiliesEx( HDC hDC
, LPLOGFONTW plf
,
811 FONTENUMPROCW efproc
,
812 LPARAM lParam
, DWORD dwUnicode
)
815 DC
*dc
= DC_GetDCPtr( hDC
);
821 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf
->lfFaceName
),
823 fe32
.lpLogFontParam
= plf
;
824 fe32
.lpEnumFunc
= efproc
;
825 fe32
.lpData
= lParam
;
826 fe32
.dwFlags
= dwUnicode
;
829 fe32
.physDev
= dc
->physDev
;
831 enum_gdi_fonts
= GetDeviceCaps(hDC
, TEXTCAPS
) & TC_VA_ABLE
;
833 if (!dc
->funcs
->pEnumDeviceFonts
&& !enum_gdi_fonts
)
840 ret
= WineEngEnumFonts( plf
, FONT_EnumInstance
, (LPARAM
)&fe32
);
841 fe32
.dwFlags
&= ~ENUM_CALLED
;
842 if (ret
&& dc
->funcs
->pEnumDeviceFonts
) {
843 ret2
= dc
->funcs
->pEnumDeviceFonts( dc
->physDev
, plf
, FONT_EnumInstance
, (LPARAM
)&fe32
);
844 if(fe32
.dwFlags
& ENUM_CALLED
) /* update ret iff a font gets enumed */
848 if (fe32
.hdc
) GDI_ReleaseObj( fe32
.hdc
);
852 /***********************************************************************
853 * EnumFontFamiliesExW (GDI32.@)
855 INT WINAPI
EnumFontFamiliesExW( HDC hDC
, LPLOGFONTW plf
,
856 FONTENUMPROCW efproc
,
857 LPARAM lParam
, DWORD dwFlags
)
859 return FONT_EnumFontFamiliesEx( hDC
, plf
, efproc
, lParam
, ENUM_UNICODE
);
862 /***********************************************************************
863 * EnumFontFamiliesExA (GDI32.@)
865 INT WINAPI
EnumFontFamiliesExA( HDC hDC
, LPLOGFONTA plf
,
866 FONTENUMPROCA efproc
,
867 LPARAM lParam
, DWORD dwFlags
)
870 FONT_LogFontAToW( plf
, &lfW
);
872 return FONT_EnumFontFamiliesEx( hDC
, &lfW
, (FONTENUMPROCW
)efproc
, lParam
, 0);
875 /***********************************************************************
876 * EnumFontFamilies (GDI.330)
878 INT16 WINAPI
EnumFontFamilies16( HDC16 hDC
, LPCSTR lpFamily
,
879 FONTENUMPROC16 efproc
, LPARAM lpData
)
883 lf
.lfCharSet
= DEFAULT_CHARSET
;
884 if( lpFamily
) lstrcpynA( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
885 else lf
.lfFaceName
[0] = '\0';
887 return EnumFontFamiliesEx16( hDC
, &lf
, efproc
, lpData
, 0 );
890 /***********************************************************************
891 * EnumFontFamiliesA (GDI32.@)
893 INT WINAPI
EnumFontFamiliesA( HDC hDC
, LPCSTR lpFamily
,
894 FONTENUMPROCA efproc
, LPARAM lpData
)
898 lf
.lfCharSet
= DEFAULT_CHARSET
;
899 if( lpFamily
) lstrcpynA( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
900 else lf
.lfFaceName
[0] = lf
.lfFaceName
[1] = '\0';
902 return EnumFontFamiliesExA( hDC
, &lf
, efproc
, lpData
, 0 );
905 /***********************************************************************
906 * EnumFontFamiliesW (GDI32.@)
908 INT WINAPI
EnumFontFamiliesW( HDC hDC
, LPCWSTR lpFamily
,
909 FONTENUMPROCW efproc
, LPARAM lpData
)
913 lf
.lfCharSet
= DEFAULT_CHARSET
;
914 if( lpFamily
) lstrcpynW( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
915 else lf
.lfFaceName
[0] = 0;
917 return EnumFontFamiliesExW( hDC
, &lf
, efproc
, lpData
, 0 );
920 /***********************************************************************
923 INT16 WINAPI
EnumFonts16( HDC16 hDC
, LPCSTR lpName
, FONTENUMPROC16 efproc
,
926 return EnumFontFamilies16( hDC
, lpName
, efproc
, lpData
);
929 /***********************************************************************
930 * EnumFontsA (GDI32.@)
932 INT WINAPI
EnumFontsA( HDC hDC
, LPCSTR lpName
, FONTENUMPROCA efproc
,
935 return EnumFontFamiliesA( hDC
, lpName
, efproc
, lpData
);
938 /***********************************************************************
939 * EnumFontsW (GDI32.@)
941 INT WINAPI
EnumFontsW( HDC hDC
, LPCWSTR lpName
, FONTENUMPROCW efproc
,
944 return EnumFontFamiliesW( hDC
, lpName
, efproc
, lpData
);
948 /***********************************************************************
949 * GetTextCharacterExtra (GDI32.@)
951 INT WINAPI
GetTextCharacterExtra( HDC hdc
)
954 DC
*dc
= DC_GetDCPtr( hdc
);
955 if (!dc
) return 0x80000000;
957 GDI_ReleaseObj( hdc
);
962 /***********************************************************************
963 * SetTextCharacterExtra (GDI32.@)
965 INT WINAPI
SetTextCharacterExtra( HDC hdc
, INT extra
)
968 DC
* dc
= DC_GetDCPtr( hdc
);
969 if (!dc
) return 0x80000000;
970 if (dc
->funcs
->pSetTextCharacterExtra
)
971 prev
= dc
->funcs
->pSetTextCharacterExtra( dc
->physDev
, extra
);
974 prev
= dc
->charExtra
;
975 dc
->charExtra
= extra
;
977 GDI_ReleaseObj( hdc
);
982 /***********************************************************************
983 * SetTextJustification (GDI32.@)
985 BOOL WINAPI
SetTextJustification( HDC hdc
, INT extra
, INT breaks
)
988 DC
* dc
= DC_GetDCPtr( hdc
);
989 if (!dc
) return FALSE
;
990 if (dc
->funcs
->pSetTextJustification
)
991 ret
= dc
->funcs
->pSetTextJustification( dc
->physDev
, extra
, breaks
);
994 extra
= abs((extra
* dc
->vportExtX
+ dc
->wndExtX
/ 2) / dc
->wndExtX
);
995 if (!extra
) breaks
= 0;
998 dc
->breakExtra
= extra
/ breaks
;
999 dc
->breakRem
= extra
- (breaks
* dc
->breakExtra
);
1007 GDI_ReleaseObj( hdc
);
1012 /***********************************************************************
1013 * GetTextFaceA (GDI32.@)
1015 INT WINAPI
GetTextFaceA( HDC hdc
, INT count
, LPSTR name
)
1017 INT res
= GetTextFaceW(hdc
, 0, NULL
);
1018 LPWSTR nameW
= HeapAlloc( GetProcessHeap(), 0, res
* 2 );
1019 GetTextFaceW( hdc
, res
, nameW
);
1023 if (count
&& !WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, name
, count
, NULL
, NULL
))
1028 res
= WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, NULL
, 0, NULL
, NULL
);
1029 HeapFree( GetProcessHeap(), 0, nameW
);
1033 /***********************************************************************
1034 * GetTextFaceW (GDI32.@)
1036 INT WINAPI
GetTextFaceW( HDC hdc
, INT count
, LPWSTR name
)
1041 DC
* dc
= DC_GetDCPtr( hdc
);
1045 ret
= WineEngGetTextFace(dc
->gdiFont
, count
, name
);
1046 else if ((font
= (FONTOBJ
*) GDI_GetObjPtr( dc
->hFont
, FONT_MAGIC
)))
1050 lstrcpynW( name
, font
->logfont
.lfFaceName
, count
);
1051 ret
= strlenW(name
);
1053 else ret
= strlenW(font
->logfont
.lfFaceName
) + 1;
1054 GDI_ReleaseObj( dc
->hFont
);
1056 GDI_ReleaseObj( hdc
);
1061 /***********************************************************************
1062 * GetTextExtentPoint32A (GDI32.@)
1064 * See GetTextExtentPoint32W.
1066 BOOL WINAPI
GetTextExtentPoint32A( HDC hdc
, LPCSTR str
, INT count
,
1071 LPWSTR p
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
1074 ret
= GetTextExtentPoint32W( hdc
, p
, wlen
, size
);
1075 HeapFree( GetProcessHeap(), 0, p
);
1078 TRACE("(%p %s %d %p): returning %ld x %ld\n",
1079 hdc
, debugstr_an (str
, count
), count
, size
, size
->cx
, size
->cy
);
1084 /***********************************************************************
1085 * GetTextExtentPoint32W [GDI32.@]
1087 * Computes width/height for a string.
1089 * Computes width and height of the specified string.
1095 BOOL WINAPI
GetTextExtentPoint32W(
1096 HDC hdc
, /* [in] Handle of device context */
1097 LPCWSTR str
, /* [in] Address of text string */
1098 INT count
, /* [in] Number of characters in string */
1099 LPSIZE size
) /* [out] Address of structure for string size */
1102 DC
* dc
= DC_GetDCPtr( hdc
);
1103 if (!dc
) return FALSE
;
1106 ret
= WineEngGetTextExtentPoint(dc
->gdiFont
, str
, count
, size
);
1107 else if(dc
->funcs
->pGetTextExtentPoint
)
1108 ret
= dc
->funcs
->pGetTextExtentPoint( dc
->physDev
, str
, count
, size
);
1112 size
->cx
= abs(INTERNAL_XDSTOWS(dc
, size
->cx
));
1113 size
->cy
= abs(INTERNAL_YDSTOWS(dc
, size
->cy
));
1114 size
->cx
+= count
* dc
->charExtra
+ dc
->breakRem
;
1117 GDI_ReleaseObj( hdc
);
1119 TRACE("(%p %s %d %p): returning %ld x %ld\n",
1120 hdc
, debugstr_wn (str
, count
), count
, size
, size
->cx
, size
->cy
);
1124 /***********************************************************************
1125 * GetTextExtentPointI [GDI32.@]
1127 * Computes width and height of the array of glyph indices.
1133 BOOL WINAPI
GetTextExtentPointI(
1134 HDC hdc
, /* [in] Handle of device context */
1135 const WORD
*indices
, /* [in] Address of glyph index array */
1136 INT count
, /* [in] Number of glyphs in array */
1137 LPSIZE size
) /* [out] Address of structure for string size */
1140 DC
* dc
= DC_GetDCPtr( hdc
);
1141 if (!dc
) return FALSE
;
1144 ret
= WineEngGetTextExtentPointI(dc
->gdiFont
, indices
, count
, size
);
1145 size
->cx
= abs(INTERNAL_XDSTOWS(dc
, size
->cx
));
1146 size
->cy
= abs(INTERNAL_YDSTOWS(dc
, size
->cy
));
1147 size
->cx
+= count
* dc
->charExtra
;
1149 else if(dc
->funcs
->pGetTextExtentPoint
) {
1150 FIXME("calling GetTextExtentPoint\n");
1151 ret
= dc
->funcs
->pGetTextExtentPoint( dc
->physDev
, (LPCWSTR
)indices
, count
, size
);
1154 GDI_ReleaseObj( hdc
);
1156 TRACE("(%p %p %d %p): returning %ld x %ld\n",
1157 hdc
, indices
, count
, size
, size
->cx
, size
->cy
);
1162 /***********************************************************************
1163 * GetTextExtentPointA (GDI32.@)
1165 BOOL WINAPI
GetTextExtentPointA( HDC hdc
, LPCSTR str
, INT count
,
1168 TRACE("not bug compatible.\n");
1169 return GetTextExtentPoint32A( hdc
, str
, count
, size
);
1172 /***********************************************************************
1173 * GetTextExtentPointW (GDI32.@)
1175 BOOL WINAPI
GetTextExtentPointW( HDC hdc
, LPCWSTR str
, INT count
,
1178 TRACE("not bug compatible.\n");
1179 return GetTextExtentPoint32W( hdc
, str
, count
, size
);
1183 /***********************************************************************
1184 * GetTextExtentExPointA (GDI32.@)
1186 BOOL WINAPI
GetTextExtentExPointA( HDC hdc
, LPCSTR str
, INT count
,
1187 INT maxExt
, LPINT lpnFit
,
1188 LPINT alpDx
, LPSIZE size
)
1192 LPWSTR p
= FONT_mbtowc( hdc
, str
, count
, &wlen
, NULL
);
1193 ret
= GetTextExtentExPointW( hdc
, p
, wlen
, maxExt
, lpnFit
, alpDx
, size
);
1194 if (lpnFit
) *lpnFit
= WideCharToMultiByte(CP_ACP
,0,p
,*lpnFit
,NULL
,0,NULL
,NULL
);
1195 HeapFree( GetProcessHeap(), 0, p
);
1200 /***********************************************************************
1201 * GetTextExtentExPointW (GDI32.@)
1203 * Return the size of the string as it would be if it was output properly by
1206 * This should include
1207 * - Intercharacter spacing
1208 * - justification spacing (not yet done)
1209 * - kerning? see below
1211 * Kerning. Since kerning would be carried out by the rendering code it should
1212 * be done by the driver. However they don't support it yet. Also I am not
1213 * yet persuaded that (certainly under Win95) any kerning is actually done.
1215 * str: According to MSDN this should be null-terminated. That is not true; a
1216 * null will not terminate it early.
1217 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1218 * than count. I have seen it be either the size of the full string or
1219 * 1 less than the size of the full string. I have not seen it bear any
1220 * resemblance to the portion that would fit.
1221 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1222 * trailing intercharacter spacing and any trailing justification.
1225 * Currently we do this by measuring each character etc. We should do it by
1226 * passing the request to the driver, perhaps by extending the
1227 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1228 * thinking about kerning issues and rounding issues in the justification.
1231 BOOL WINAPI
GetTextExtentExPointW( HDC hdc
, LPCWSTR str
, INT count
,
1232 INT maxExt
, LPINT lpnFit
,
1233 LPINT alpDx
, LPSIZE size
)
1235 int index
, nFit
, extent
;
1239 TRACE("(%p, %s, %d)\n",hdc
,debugstr_wn(str
,count
),maxExt
);
1241 size
->cx
= size
->cy
= nFit
= extent
= 0;
1242 for(index
= 0; index
< count
; index
++)
1244 if(!GetTextExtentPoint32W( hdc
, str
, 1, &tSize
)) goto done
;
1245 /* GetTextExtentPoint includes intercharacter spacing. */
1246 /* FIXME - justification needs doing yet. Remember that the base
1247 * data will not be in logical coordinates.
1250 if( !lpnFit
|| extent
<= maxExt
)
1251 /* It is allowed to be equal. */
1254 if( alpDx
) alpDx
[index
] = extent
;
1256 if( tSize
.cy
> size
->cy
) size
->cy
= tSize
.cy
;
1260 if(lpnFit
) *lpnFit
= nFit
;
1263 TRACE("returning %d %ld x %ld\n",nFit
,size
->cx
,size
->cy
);
1269 /***********************************************************************
1270 * GetTextMetricsA (GDI32.@)
1272 BOOL WINAPI
GetTextMetricsA( HDC hdc
, TEXTMETRICA
*metrics
)
1276 if (!GetTextMetricsW( hdc
, &tm32
)) return FALSE
;
1277 FONT_TextMetricWToA( &tm32
, metrics
);
1281 /***********************************************************************
1282 * GetTextMetricsW (GDI32.@)
1284 BOOL WINAPI
GetTextMetricsW( HDC hdc
, TEXTMETRICW
*metrics
)
1287 DC
* dc
= DC_GetDCPtr( hdc
);
1288 if (!dc
) return FALSE
;
1291 ret
= WineEngGetTextMetrics(dc
->gdiFont
, metrics
);
1292 else if (dc
->funcs
->pGetTextMetrics
)
1293 ret
= dc
->funcs
->pGetTextMetrics( dc
->physDev
, metrics
);
1297 /* device layer returns values in device units
1298 * therefore we have to convert them to logical */
1300 #define WDPTOLP(x) ((x<0)? \
1301 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1302 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1303 #define HDPTOLP(y) ((y<0)? \
1304 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1305 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1307 metrics
->tmHeight
= HDPTOLP(metrics
->tmHeight
);
1308 metrics
->tmAscent
= HDPTOLP(metrics
->tmAscent
);
1309 metrics
->tmDescent
= HDPTOLP(metrics
->tmDescent
);
1310 metrics
->tmInternalLeading
= HDPTOLP(metrics
->tmInternalLeading
);
1311 metrics
->tmExternalLeading
= HDPTOLP(metrics
->tmExternalLeading
);
1312 metrics
->tmAveCharWidth
= WDPTOLP(metrics
->tmAveCharWidth
);
1313 metrics
->tmMaxCharWidth
= WDPTOLP(metrics
->tmMaxCharWidth
);
1314 metrics
->tmOverhang
= WDPTOLP(metrics
->tmOverhang
);
1318 TRACE("text metrics:\n"
1319 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1320 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1321 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1322 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1323 " PitchAndFamily = %02x\n"
1324 " --------------------\n"
1325 " InternalLeading = %li\n"
1329 metrics
->tmWeight
, metrics
->tmFirstChar
, metrics
->tmAveCharWidth
,
1330 metrics
->tmItalic
, metrics
->tmLastChar
, metrics
->tmMaxCharWidth
,
1331 metrics
->tmUnderlined
, metrics
->tmDefaultChar
, metrics
->tmOverhang
,
1332 metrics
->tmStruckOut
, metrics
->tmBreakChar
, metrics
->tmCharSet
,
1333 metrics
->tmPitchAndFamily
,
1334 metrics
->tmInternalLeading
,
1337 metrics
->tmHeight
);
1339 GDI_ReleaseObj( hdc
);
1344 /***********************************************************************
1345 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1348 * lpOTM should be LPOUTLINETEXTMETRIC
1351 * Success: Non-zero or size of required buffer
1354 UINT16 WINAPI
GetOutlineTextMetrics16(
1355 HDC16 hdc
, /* [in] Handle of device context */
1356 UINT16 cbData
, /* [in] Size of metric data array */
1357 LPOUTLINETEXTMETRIC16 lpOTM
) /* [out] Address of metric data array */
1359 FIXME("(%04x,%04x,%p): stub\n", hdc
,cbData
,lpOTM
);
1364 /***********************************************************************
1365 * GetOutlineTextMetricsA (GDI32.@)
1366 * Gets metrics for TrueType fonts.
1369 * If the supplied buffer isn't big enough Windows partially fills it up to
1370 * its given length and returns that length.
1373 * Success: Non-zero or size of required buffer
1376 UINT WINAPI
GetOutlineTextMetricsA(
1377 HDC hdc
, /* [in] Handle of device context */
1378 UINT cbData
, /* [in] Size of metric data array */
1379 LPOUTLINETEXTMETRICA lpOTM
) /* [out] Address of metric data array */
1381 char buf
[512], *ptr
;
1383 OUTLINETEXTMETRICW
*lpOTMW
= (OUTLINETEXTMETRICW
*)buf
;
1384 OUTLINETEXTMETRICA
*output
= lpOTM
;
1387 if((ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
)) == 0)
1389 if(ret
> sizeof(buf
))
1390 lpOTMW
= HeapAlloc(GetProcessHeap(), 0, ret
);
1391 GetOutlineTextMetricsW(hdc
, ret
, lpOTMW
);
1393 needed
= sizeof(OUTLINETEXTMETRICA
);
1394 if(lpOTMW
->otmpFamilyName
)
1395 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1396 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFamilyName
), -1,
1397 NULL
, 0, NULL
, NULL
);
1398 if(lpOTMW
->otmpFaceName
)
1399 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1400 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFaceName
), -1,
1401 NULL
, 0, NULL
, NULL
);
1402 if(lpOTMW
->otmpStyleName
)
1403 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1404 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpStyleName
), -1,
1405 NULL
, 0, NULL
, NULL
);
1406 if(lpOTMW
->otmpFullName
)
1407 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1408 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFullName
), -1,
1409 NULL
, 0, NULL
, NULL
);
1416 TRACE("needed = %d\n", needed
);
1418 /* Since the supplied buffer isn't big enough, we'll alloc one
1419 that is and memcpy the first cbData bytes into the lpOTM at
1421 output
= HeapAlloc(GetProcessHeap(), 0, needed
);
1423 ret
= output
->otmSize
= min(needed
, cbData
);
1424 FONT_TextMetricWToA( &lpOTMW
->otmTextMetrics
, &output
->otmTextMetrics
);
1425 output
->otmFiller
= 0;
1426 output
->otmPanoseNumber
= lpOTMW
->otmPanoseNumber
;
1427 output
->otmfsSelection
= lpOTMW
->otmfsSelection
;
1428 output
->otmfsType
= lpOTMW
->otmfsType
;
1429 output
->otmsCharSlopeRise
= lpOTMW
->otmsCharSlopeRise
;
1430 output
->otmsCharSlopeRun
= lpOTMW
->otmsCharSlopeRun
;
1431 output
->otmItalicAngle
= lpOTMW
->otmItalicAngle
;
1432 output
->otmEMSquare
= lpOTMW
->otmEMSquare
;
1433 output
->otmAscent
= lpOTMW
->otmAscent
;
1434 output
->otmDescent
= lpOTMW
->otmDescent
;
1435 output
->otmLineGap
= lpOTMW
->otmLineGap
;
1436 output
->otmsCapEmHeight
= lpOTMW
->otmsCapEmHeight
;
1437 output
->otmsXHeight
= lpOTMW
->otmsXHeight
;
1438 output
->otmrcFontBox
= lpOTMW
->otmrcFontBox
;
1439 output
->otmMacAscent
= lpOTMW
->otmMacAscent
;
1440 output
->otmMacDescent
= lpOTMW
->otmMacDescent
;
1441 output
->otmMacLineGap
= lpOTMW
->otmMacLineGap
;
1442 output
->otmusMinimumPPEM
= lpOTMW
->otmusMinimumPPEM
;
1443 output
->otmptSubscriptSize
= lpOTMW
->otmptSubscriptSize
;
1444 output
->otmptSubscriptOffset
= lpOTMW
->otmptSubscriptOffset
;
1445 output
->otmptSuperscriptSize
= lpOTMW
->otmptSuperscriptSize
;
1446 output
->otmptSuperscriptOffset
= lpOTMW
->otmptSuperscriptOffset
;
1447 output
->otmsStrikeoutSize
= lpOTMW
->otmsStrikeoutSize
;
1448 output
->otmsStrikeoutPosition
= lpOTMW
->otmsStrikeoutPosition
;
1449 output
->otmsUnderscoreSize
= lpOTMW
->otmsUnderscoreSize
;
1450 output
->otmsUnderscorePosition
= lpOTMW
->otmsUnderscorePosition
;
1453 ptr
= (char*)(output
+ 1);
1454 left
= needed
- sizeof(*output
);
1456 if(lpOTMW
->otmpFamilyName
) {
1457 output
->otmpFamilyName
= (LPSTR
)(ptr
- (char*)output
);
1458 len
= WideCharToMultiByte(CP_ACP
, 0,
1459 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFamilyName
), -1,
1460 ptr
, left
, NULL
, NULL
);
1464 output
->otmpFamilyName
= 0;
1466 if(lpOTMW
->otmpFaceName
) {
1467 output
->otmpFaceName
= (LPSTR
)(ptr
- (char*)output
);
1468 len
= WideCharToMultiByte(CP_ACP
, 0,
1469 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFaceName
), -1,
1470 ptr
, left
, NULL
, NULL
);
1474 output
->otmpFaceName
= 0;
1476 if(lpOTMW
->otmpStyleName
) {
1477 output
->otmpStyleName
= (LPSTR
)(ptr
- (char*)output
);
1478 len
= WideCharToMultiByte(CP_ACP
, 0,
1479 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpStyleName
), -1,
1480 ptr
, left
, NULL
, NULL
);
1484 output
->otmpStyleName
= 0;
1486 if(lpOTMW
->otmpFullName
) {
1487 output
->otmpFullName
= (LPSTR
)(ptr
- (char*)output
);
1488 len
= WideCharToMultiByte(CP_ACP
, 0,
1489 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFullName
), -1,
1490 ptr
, left
, NULL
, NULL
);
1493 output
->otmpFullName
= 0;
1497 if(output
!= lpOTM
) {
1498 memcpy(lpOTM
, output
, cbData
);
1499 HeapFree(GetProcessHeap(), 0, output
);
1503 if(lpOTMW
!= (OUTLINETEXTMETRICW
*)buf
)
1504 HeapFree(GetProcessHeap(), 0, lpOTMW
);
1510 /***********************************************************************
1511 * GetOutlineTextMetricsW [GDI32.@]
1513 UINT WINAPI
GetOutlineTextMetricsW(
1514 HDC hdc
, /* [in] Handle of device context */
1515 UINT cbData
, /* [in] Size of metric data array */
1516 LPOUTLINETEXTMETRICW lpOTM
) /* [out] Address of metric data array */
1518 DC
*dc
= DC_GetDCPtr( hdc
);
1519 OUTLINETEXTMETRICW
*output
= lpOTM
;
1522 TRACE("(%p,%d,%p)\n", hdc
, cbData
, lpOTM
);
1526 ret
= WineEngGetOutlineTextMetrics(dc
->gdiFont
, cbData
, output
);
1529 output
= HeapAlloc(GetProcessHeap(), 0, ret
);
1530 WineEngGetOutlineTextMetrics(dc
->gdiFont
, ret
, output
);
1533 #define WDPTOLP(x) ((x<0)? \
1534 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1535 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1536 #define HDPTOLP(y) ((y<0)? \
1537 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1538 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1540 output
->otmTextMetrics
.tmHeight
= HDPTOLP(output
->otmTextMetrics
.tmHeight
);
1541 output
->otmTextMetrics
.tmAscent
= HDPTOLP(output
->otmTextMetrics
.tmAscent
);
1542 output
->otmTextMetrics
.tmDescent
= HDPTOLP(output
->otmTextMetrics
.tmDescent
);
1543 output
->otmTextMetrics
.tmInternalLeading
= HDPTOLP(output
->otmTextMetrics
.tmInternalLeading
);
1544 output
->otmTextMetrics
.tmExternalLeading
= HDPTOLP(output
->otmTextMetrics
.tmExternalLeading
);
1545 output
->otmTextMetrics
.tmAveCharWidth
= WDPTOLP(output
->otmTextMetrics
.tmAveCharWidth
);
1546 output
->otmTextMetrics
.tmMaxCharWidth
= WDPTOLP(output
->otmTextMetrics
.tmMaxCharWidth
);
1547 output
->otmTextMetrics
.tmOverhang
= WDPTOLP(output
->otmTextMetrics
.tmOverhang
);
1548 output
->otmAscent
= HDPTOLP(output
->otmAscent
);
1549 output
->otmDescent
= HDPTOLP(output
->otmDescent
);
1550 output
->otmLineGap
= HDPTOLP(output
->otmLineGap
);
1551 output
->otmsCapEmHeight
= HDPTOLP(output
->otmsCapEmHeight
);
1552 output
->otmsXHeight
= HDPTOLP(output
->otmsXHeight
);
1553 output
->otmrcFontBox
.top
= HDPTOLP(output
->otmrcFontBox
.top
);
1554 output
->otmrcFontBox
.bottom
= HDPTOLP(output
->otmrcFontBox
.bottom
);
1555 output
->otmrcFontBox
.left
= WDPTOLP(output
->otmrcFontBox
.left
);
1556 output
->otmrcFontBox
.right
= WDPTOLP(output
->otmrcFontBox
.right
);
1557 output
->otmMacAscent
= HDPTOLP(output
->otmMacAscent
);
1558 output
->otmMacDescent
= HDPTOLP(output
->otmMacDescent
);
1559 output
->otmMacLineGap
= HDPTOLP(output
->otmMacLineGap
);
1560 output
->otmptSubscriptSize
.x
= WDPTOLP(output
->otmptSubscriptSize
.x
);
1561 output
->otmptSubscriptSize
.y
= HDPTOLP(output
->otmptSubscriptSize
.y
);
1562 output
->otmptSubscriptOffset
.x
= WDPTOLP(output
->otmptSubscriptOffset
.x
);
1563 output
->otmptSubscriptOffset
.y
= HDPTOLP(output
->otmptSubscriptOffset
.y
);
1564 output
->otmptSuperscriptSize
.x
= WDPTOLP(output
->otmptSuperscriptSize
.x
);
1565 output
->otmptSuperscriptSize
.y
= HDPTOLP(output
->otmptSuperscriptSize
.y
);
1566 output
->otmptSuperscriptOffset
.x
= WDPTOLP(output
->otmptSuperscriptOffset
.x
);
1567 output
->otmptSuperscriptOffset
.y
= HDPTOLP(output
->otmptSuperscriptOffset
.y
);
1568 output
->otmsStrikeoutSize
= HDPTOLP(output
->otmsStrikeoutSize
);
1569 output
->otmsStrikeoutPosition
= HDPTOLP(output
->otmsStrikeoutPosition
);
1570 output
->otmsUnderscoreSize
= HDPTOLP(output
->otmsUnderscoreSize
);
1571 output
->otmsUnderscorePosition
= HDPTOLP(output
->otmsUnderscorePosition
);
1574 if(output
!= lpOTM
) {
1575 memcpy(lpOTM
, output
, cbData
);
1576 HeapFree(GetProcessHeap(), 0, output
);
1582 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1583 but really this should just be a return 0. */
1585 ret
= sizeof(*lpOTM
);
1590 memset(lpOTM
, 0, ret
);
1591 lpOTM
->otmSize
= sizeof(*lpOTM
);
1592 GetTextMetricsW(hdc
, &lpOTM
->otmTextMetrics
);
1594 Further fill of the structure not implemented,
1595 Needs real values for the structure members
1600 GDI_ReleaseObj(hdc
);
1605 /***********************************************************************
1606 * GetCharWidthW (GDI32.@)
1607 * GetCharWidth32W (GDI32.@)
1609 BOOL WINAPI
GetCharWidth32W( HDC hdc
, UINT firstChar
, UINT lastChar
,
1614 DC
* dc
= DC_GetDCPtr( hdc
);
1615 if (!dc
) return FALSE
;
1618 ret
= WineEngGetCharWidth( dc
->gdiFont
, firstChar
, lastChar
, buffer
);
1619 else if (dc
->funcs
->pGetCharWidth
)
1620 ret
= dc
->funcs
->pGetCharWidth( dc
->physDev
, firstChar
, lastChar
, buffer
);
1624 /* convert device units to logical */
1625 for( i
= firstChar
; i
<= lastChar
; i
++, buffer
++ )
1626 *buffer
= INTERNAL_XDSTOWS(dc
, *buffer
);
1629 GDI_ReleaseObj( hdc
);
1634 /***********************************************************************
1635 * GetCharWidthA (GDI32.@)
1636 * GetCharWidth32A (GDI32.@)
1638 BOOL WINAPI
GetCharWidth32A( HDC hdc
, UINT firstChar
, UINT lastChar
,
1641 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
1646 if(count
<= 0) return FALSE
;
1648 str
= HeapAlloc(GetProcessHeap(), 0, count
);
1649 for(i
= 0; i
< count
; i
++)
1650 str
[i
] = (BYTE
)(firstChar
+ i
);
1652 wstr
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
1654 for(i
= 0; i
< wlen
; i
++)
1656 if(!GetCharWidth32W(hdc
, wstr
[i
], wstr
[i
], buffer
))
1664 HeapFree(GetProcessHeap(), 0, str
);
1665 HeapFree(GetProcessHeap(), 0, wstr
);
1671 /***********************************************************************
1672 * ExtTextOutA (GDI32.@)
1676 BOOL WINAPI
ExtTextOutA( HDC hdc
, INT x
, INT y
, UINT flags
,
1677 const RECT
*lprect
, LPCSTR str
, UINT count
, const INT
*lpDx
)
1681 LPWSTR p
= FONT_mbtowc(hdc
, str
, count
, &wlen
, &codepage
);
1686 unsigned int i
= 0, j
= 0;
1688 lpDxW
= HeapAlloc( GetProcessHeap(), 0, wlen
*sizeof(INT
));
1690 if(IsDBCSLeadByteEx(codepage
, str
[i
])) {
1691 lpDxW
[j
++] = lpDx
[i
] + lpDx
[i
+1];
1694 lpDxW
[j
++] = lpDx
[i
];
1700 ret
= ExtTextOutW( hdc
, x
, y
, flags
, lprect
, p
, wlen
, lpDxW
);
1702 HeapFree( GetProcessHeap(), 0, p
);
1703 HeapFree( GetProcessHeap(), 0, lpDxW
);
1708 /***********************************************************************
1709 * ExtTextOutW (GDI32.@)
1711 * Draws text using the currently selected font, background color, and text color.
1715 * x,y [I] coordinates of string
1717 * ETO_GRAYED - undocumented on MSDN
1718 * ETO_OPAQUE - use background color for fill the rectangle
1719 * ETO_CLIPPED - clipping text to the rectangle
1720 * ETO_GLYPH_INDEX - Buffer is of glyph locations in fonts rather
1721 * than encoded characters. Implies ETO_IGNORELANGUAGE
1722 * ETO_RTLREADING - Paragraph is basically a right-to-left paragraph.
1723 * Affects BiDi ordering
1724 * ETO_IGNORELANGUAGE - Undocumented in MSDN - instructs ExtTextOut not to do BiDi reordering
1725 * ETO_PDY - unimplemented
1726 * ETO_NUMERICSLATIN - unimplemented always assumed -
1727 * do not translate numbers into locale representations
1728 * ETO_NUMERICSLOCAL - unimplemented - Numerals in Arabic/Farsi context should assume local form
1729 * lprect [I] dimensions for clipping or/and opaquing
1730 * str [I] text string
1731 * count [I] number of symbols in string
1732 * lpDx [I] optional parameter with distance between drawing characters
1738 BOOL WINAPI
ExtTextOutW( HDC hdc
, INT x
, INT y
, UINT flags
,
1739 const RECT
*lprect
, LPCWSTR str
, UINT count
, const INT
*lpDx
)
1742 LPWSTR reordered_str
= (LPWSTR
)str
;
1743 WORD
*glyphs
= NULL
;
1744 UINT align
= GetTextAlign( hdc
);
1748 double cosEsc
, sinEsc
;
1749 INT
*deltas
= NULL
, char_extra
;
1752 BOOL done_extents
= FALSE
;
1753 INT width
, xwidth
= 0, ywidth
= 0;
1755 DC
* dc
= DC_GetDCUpdate( hdc
);
1757 if (!dc
) return FALSE
;
1759 if (flags
& (ETO_NUMERICSLOCAL
| ETO_NUMERICSLATIN
| ETO_PDY
))
1760 FIXME("flags ETO_NUMERICSLOCAL | ETO_NUMERICSLATIN | ETO_PDY unimplemented\n");
1762 if(PATH_IsPathOpen(dc
->path
))
1764 FIXME("called on an open path\n");
1765 GDI_ReleaseObj( hdc
);
1769 if(!dc
->funcs
->pExtTextOut
)
1771 GDI_ReleaseObj( hdc
);
1775 type
= GetObjectType(hdc
);
1776 if(type
== OBJ_METADC
|| type
== OBJ_ENHMETADC
)
1778 ret
= dc
->funcs
->pExtTextOut(dc
->physDev
, x
, y
, flags
, lprect
, str
, count
, lpDx
);
1779 GDI_ReleaseObj( hdc
);
1783 if( !(flags
& (ETO_GLYPH_INDEX
| ETO_IGNORELANGUAGE
)) && BidiAvail
&& count
> 0 )
1785 reordered_str
= HeapAlloc(GetProcessHeap(), 0, count
*sizeof(WCHAR
));
1787 BIDI_Reorder( str
, count
, GCP_REORDER
,
1788 ((flags
&ETO_RTLREADING
)!=0 || (GetTextAlign(hdc
)&TA_RTLREADING
)!=0)?
1789 WINE_GCPW_FORCE_RTL
:WINE_GCPW_FORCE_LTR
,
1790 reordered_str
, count
, NULL
);
1792 flags
|= ETO_IGNORELANGUAGE
;
1795 TRACE("%p, %d, %d, %08x, %p, %s, %d, %p)\n", hdc
, x
, y
, flags
,
1796 lprect
, debugstr_wn(str
, count
), count
, lpDx
);
1798 if(flags
& ETO_GLYPH_INDEX
)
1799 glyphs
= reordered_str
;
1802 TRACE("rect: %ld,%ld - %ld,%ld\n", lprect
->left
, lprect
->top
, lprect
->right
,
1804 TRACE("align = %x bkmode = %x mapmode = %x\n", align
, GetBkMode(hdc
), GetMapMode(hdc
));
1806 if(align
& TA_UPDATECP
)
1808 GetCurrentPositionEx( hdc
, &pt
);
1813 GetTextMetricsW(hdc
, &tm
);
1814 GetObjectW(GetCurrentObject(hdc
, OBJ_FONT
), sizeof(lf
), &lf
);
1816 if(!(tm
.tmPitchAndFamily
& TMPF_VECTOR
)) /* Non-scalable fonts shouldn't be rotated */
1817 lf
.lfEscapement
= 0;
1819 if(lf
.lfEscapement
!= 0)
1821 cosEsc
= cos(lf
.lfEscapement
* M_PI
/ 1800);
1822 sinEsc
= sin(lf
.lfEscapement
* M_PI
/ 1800);
1830 if(flags
& (ETO_CLIPPED
| ETO_OPAQUE
))
1834 if(flags
& ETO_CLIPPED
) goto done
;
1835 if(flags
& ETO_GLYPH_INDEX
)
1836 GetTextExtentPointI(hdc
, glyphs
, count
, &sz
);
1838 GetTextExtentPointW(hdc
, reordered_str
, count
, &sz
);
1840 done_extents
= TRUE
;
1843 rc
.right
= x
+ sz
.cx
;
1844 rc
.bottom
= y
+ sz
.cy
;
1851 LPtoDP(hdc
, (POINT
*)&rc
, 2);
1853 if(rc
.left
> rc
.right
) {INT tmp
= rc
.left
; rc
.left
= rc
.right
; rc
.right
= tmp
;}
1854 if(rc
.top
> rc
.bottom
) {INT tmp
= rc
.top
; rc
.top
= rc
.bottom
; rc
.bottom
= tmp
;}
1857 if(flags
& ETO_OPAQUE
)
1858 dc
->funcs
->pExtTextOut(dc
->physDev
, 0, 0, ETO_OPAQUE
, &rc
, NULL
, 0, NULL
);
1868 LPtoDP(hdc
, &pt
, 1);
1872 char_extra
= GetTextCharacterExtra(hdc
);
1874 if(char_extra
|| dc
->breakExtra
|| lpDx
)
1878 deltas
= HeapAlloc(GetProcessHeap(), 0, count
* sizeof(INT
));
1879 for(i
= 0; i
< count
; i
++)
1882 deltas
[i
] = lpDx
[i
] + char_extra
;
1885 if(flags
& ETO_GLYPH_INDEX
)
1886 GetTextExtentPointI(hdc
, glyphs
+ i
, 1, &tmpsz
);
1888 GetTextExtentPointW(hdc
, reordered_str
+ i
, 1, &tmpsz
);
1890 deltas
[i
] = tmpsz
.cx
;
1893 if (!(flags
& ETO_GLYPH_INDEX
) && dc
->breakExtra
&& reordered_str
[i
] == tm
.tmBreakChar
)
1895 deltas
[i
] = deltas
[i
] + dc
->breakExtra
;
1897 deltas
[i
] = INTERNAL_XWSTODS(dc
, deltas
[i
]);
1905 if(flags
& ETO_GLYPH_INDEX
)
1906 GetTextExtentPointI(hdc
, glyphs
, count
, &sz
);
1908 GetTextExtentPointW(hdc
, reordered_str
, count
, &sz
);
1909 done_extents
= TRUE
;
1911 width
= INTERNAL_XWSTODS(dc
, sz
.cx
);
1913 xwidth
= width
* cosEsc
;
1914 ywidth
= width
* sinEsc
;
1916 tm
.tmAscent
= abs(INTERNAL_YWSTODS(dc
, tm
.tmAscent
));
1917 tm
.tmDescent
= abs(INTERNAL_YWSTODS(dc
, tm
.tmDescent
));
1918 switch( align
& (TA_LEFT
| TA_RIGHT
| TA_CENTER
) )
1921 if (align
& TA_UPDATECP
)
1925 DPtoLP(hdc
, &pt
, 1);
1926 MoveToEx(hdc
, pt
.x
, pt
.y
, NULL
);
1938 if (align
& TA_UPDATECP
)
1942 DPtoLP(hdc
, &pt
, 1);
1943 MoveToEx(hdc
, pt
.x
, pt
.y
, NULL
);
1948 switch( align
& (TA_TOP
| TA_BOTTOM
| TA_BASELINE
) )
1951 y
+= tm
.tmAscent
* cosEsc
;
1952 x
+= tm
.tmAscent
* sinEsc
;
1956 y
-= tm
.tmDescent
* cosEsc
;
1957 x
-= tm
.tmDescent
* sinEsc
;
1964 if(GetBkMode(hdc
) != TRANSPARENT
)
1966 if(!((flags
& ETO_CLIPPED
) && (flags
& ETO_OPAQUE
)))
1968 if(!(flags
& ETO_OPAQUE
) || x
< rc
.left
|| x
+ width
>= rc
.right
||
1969 y
- tm
.tmAscent
< rc
.top
|| y
+ tm
.tmDescent
>= rc
.bottom
)
1973 rc
.right
= x
+ width
;
1974 rc
.top
= y
- tm
.tmAscent
;
1975 rc
.bottom
= y
+ tm
.tmDescent
;
1976 dc
->funcs
->pExtTextOut(dc
->physDev
, 0, 0, ETO_OPAQUE
, &rc
, NULL
, 0, NULL
);
1981 if(FontIsLinked(hdc
) && !(flags
& ETO_GLYPH_INDEX
))
1983 HFONT orig_font
= dc
->hFont
, cur_font
;
1985 INT span
= 0, *offsets
= NULL
, i
;
1987 glyphs
= HeapAlloc(GetProcessHeap(), 0, count
* sizeof(WORD
));
1988 for(i
= 0; i
< count
; i
++)
1990 WineEngGetLinkedHFont(dc
, reordered_str
[i
], &cur_font
, &glyph
);
1991 if(cur_font
!= dc
->hFont
)
1996 offsets
= HeapAlloc(GetProcessHeap(), 0, count
* sizeof(*deltas
));
2001 for(j
= 1; j
< count
; j
++)
2003 GetTextExtentPointW(hdc
, reordered_str
+ j
- 1, 1, &tmpsz
);
2004 offsets
[j
] = offsets
[j
-1] + INTERNAL_XWSTODS(dc
, tmpsz
.cx
);
2009 for(j
= 1; j
< count
; j
++)
2010 offsets
[j
] = offsets
[j
-1] + deltas
[j
];
2015 dc
->funcs
->pExtTextOut(dc
->physDev
, x
+ offsets
[i
- span
] * cosEsc
, y
- offsets
[i
- span
] * sinEsc
,
2016 (flags
& ~ETO_OPAQUE
) | ETO_GLYPH_INDEX
, &rc
,
2017 glyphs
, span
, deltas
? deltas
+ i
- span
: NULL
);
2020 SelectObject(hdc
, cur_font
);
2022 glyphs
[span
++] = glyph
;
2026 ret
= dc
->funcs
->pExtTextOut(dc
->physDev
, x
+ (offsets
? offsets
[count
- span
] * cosEsc
: 0),
2027 y
- (offsets
? offsets
[count
- span
] * sinEsc
: 0),
2028 (flags
& ~ETO_OPAQUE
) | ETO_GLYPH_INDEX
, &rc
,
2029 glyphs
, span
, deltas
? deltas
+ count
- span
: NULL
);
2030 SelectObject(hdc
, orig_font
);
2031 HeapFree(GetProcessHeap(), 0, offsets
);
2037 if(!(flags
& ETO_GLYPH_INDEX
) && dc
->gdiFont
)
2039 glyphs
= HeapAlloc(GetProcessHeap(), 0, count
* sizeof(WORD
));
2040 GetGlyphIndicesW(hdc
, reordered_str
, count
, glyphs
, 0);
2041 flags
|= ETO_GLYPH_INDEX
;
2043 ret
= dc
->funcs
->pExtTextOut(dc
->physDev
, x
, y
, (flags
& ~ETO_OPAQUE
), &rc
,
2044 glyphs
? glyphs
: reordered_str
, count
, deltas
);
2048 HeapFree(GetProcessHeap(), 0, deltas
);
2049 if(glyphs
!= reordered_str
)
2050 HeapFree(GetProcessHeap(), 0, glyphs
);
2051 if(reordered_str
!= str
)
2052 HeapFree(GetProcessHeap(), 0, reordered_str
);
2054 GDI_ReleaseObj( hdc
);
2056 if (ret
&& (lf
.lfUnderline
|| lf
.lfStrikeOut
))
2058 int underlinePos
, strikeoutPos
;
2059 int underlineWidth
, strikeoutWidth
;
2060 UINT size
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
2061 OUTLINETEXTMETRICW
* otm
= NULL
;
2066 underlineWidth
= tm
.tmAscent
/ 20 + 1;
2067 strikeoutPos
= tm
.tmAscent
/ 2;
2068 strikeoutWidth
= underlineWidth
;
2072 otm
= HeapAlloc(GetProcessHeap(), 0, size
);
2073 GetOutlineTextMetricsW(hdc
, size
, otm
);
2074 underlinePos
= otm
->otmsUnderscorePosition
;
2075 underlineWidth
= otm
->otmsUnderscoreSize
;
2076 strikeoutPos
= otm
->otmsStrikeoutPosition
;
2077 strikeoutWidth
= otm
->otmsStrikeoutSize
;
2078 HeapFree(GetProcessHeap(), 0, otm
);
2081 if (PATH_IsPathOpen(dc
->path
))
2085 HBRUSH hbrush
= CreateSolidBrush(GetTextColor(hdc
));
2087 hbrush
= SelectObject(hdc
, hbrush
);
2088 hpen
= SelectObject(hdc
, GetStockObject(NULL_PEN
));
2092 pts
[0].x
= x
- underlinePos
* sinEsc
;
2093 pts
[0].y
= y
- underlinePos
* cosEsc
;
2094 pts
[1].x
= x
+ xwidth
- underlinePos
* sinEsc
;
2095 pts
[1].y
= y
- ywidth
- underlinePos
* cosEsc
;
2096 pts
[2].x
= pts
[1].x
+ underlineWidth
* sinEsc
;
2097 pts
[2].y
= pts
[1].y
+ underlineWidth
* cosEsc
;
2098 pts
[3].x
= pts
[0].x
+ underlineWidth
* sinEsc
;
2099 pts
[3].y
= pts
[0].y
+ underlineWidth
* cosEsc
;
2100 pts
[4].x
= pts
[0].x
;
2101 pts
[4].y
= pts
[0].y
;
2102 DPtoLP(hdc
, pts
, 5);
2103 Polygon(hdc
, pts
, 5);
2108 pts
[0].x
= x
- strikeoutPos
* sinEsc
;
2109 pts
[0].y
= y
- strikeoutPos
* cosEsc
;
2110 pts
[1].x
= x
+ xwidth
- strikeoutPos
* sinEsc
;
2111 pts
[1].y
= y
- ywidth
- strikeoutPos
* cosEsc
;
2112 pts
[2].x
= pts
[1].x
+ strikeoutWidth
* sinEsc
;
2113 pts
[2].y
= pts
[1].y
+ strikeoutWidth
* cosEsc
;
2114 pts
[3].x
= pts
[0].x
+ strikeoutWidth
* sinEsc
;
2115 pts
[3].y
= pts
[0].y
+ strikeoutWidth
* cosEsc
;
2116 pts
[4].x
= pts
[0].x
;
2117 pts
[4].y
= pts
[0].y
;
2118 DPtoLP(hdc
, pts
, 5);
2119 Polygon(hdc
, pts
, 5);
2122 SelectObject(hdc
, hpen
);
2123 hbrush
= SelectObject(hdc
, hbrush
);
2124 DeleteObject(hbrush
);
2128 POINT pts
[2], oldpt
;
2133 hpen
= CreatePen(PS_SOLID
, underlineWidth
, GetTextColor(hdc
));
2134 hpen
= SelectObject(hdc
, hpen
);
2137 pts
[1].x
= x
+ xwidth
;
2138 pts
[1].y
= y
- ywidth
;
2139 DPtoLP(hdc
, pts
, 2);
2140 MoveToEx(hdc
, pts
[0].x
- underlinePos
* sinEsc
, pts
[0].y
- underlinePos
* cosEsc
, &oldpt
);
2141 LineTo(hdc
, pts
[1].x
- underlinePos
* sinEsc
, pts
[1].y
- underlinePos
* cosEsc
);
2142 MoveToEx(hdc
, oldpt
.x
, oldpt
.y
, NULL
);
2143 DeleteObject(SelectObject(hdc
, hpen
));
2148 hpen
= CreatePen(PS_SOLID
, strikeoutWidth
, GetTextColor(hdc
));
2149 hpen
= SelectObject(hdc
, hpen
);
2152 pts
[1].x
= x
+ xwidth
;
2153 pts
[1].y
= y
- ywidth
;
2154 DPtoLP(hdc
, pts
, 2);
2155 MoveToEx(hdc
, pts
[0].x
- strikeoutPos
* sinEsc
, pts
[0].y
- strikeoutPos
* cosEsc
, &oldpt
);
2156 LineTo(hdc
, pts
[1].x
- strikeoutPos
* sinEsc
, pts
[1].y
- strikeoutPos
* cosEsc
);
2157 MoveToEx(hdc
, oldpt
.x
, oldpt
.y
, NULL
);
2158 DeleteObject(SelectObject(hdc
, hpen
));
2167 /***********************************************************************
2168 * TextOutA (GDI32.@)
2170 BOOL WINAPI
TextOutA( HDC hdc
, INT x
, INT y
, LPCSTR str
, INT count
)
2172 return ExtTextOutA( hdc
, x
, y
, 0, NULL
, str
, count
, NULL
);
2176 /***********************************************************************
2177 * TextOutW (GDI32.@)
2179 BOOL WINAPI
TextOutW(HDC hdc
, INT x
, INT y
, LPCWSTR str
, INT count
)
2181 return ExtTextOutW( hdc
, x
, y
, 0, NULL
, str
, count
, NULL
);
2185 /***********************************************************************
2186 * PolyTextOutA (GDI32.@)
2190 BOOL WINAPI
PolyTextOutA ( HDC hdc
, /* [in] Handle to device context */
2191 PPOLYTEXTA pptxt
, /* [in] Array of strings */
2192 INT cStrings
) /* [in] Number of strings in array */
2194 for (; cStrings
>0; cStrings
--, pptxt
++)
2195 if (!ExtTextOutA( hdc
, pptxt
->x
, pptxt
->y
, pptxt
->uiFlags
, &pptxt
->rcl
, pptxt
->lpstr
, pptxt
->n
, pptxt
->pdx
))
2202 /***********************************************************************
2203 * PolyTextOutW (GDI32.@)
2205 * Draw several Strings
2211 BOOL WINAPI
PolyTextOutW ( HDC hdc
, /* [in] Handle to device context */
2212 PPOLYTEXTW pptxt
, /* [in] Array of strings */
2213 INT cStrings
) /* [in] Number of strings in array */
2215 for (; cStrings
>0; cStrings
--, pptxt
++)
2216 if (!ExtTextOutW( hdc
, pptxt
->x
, pptxt
->y
, pptxt
->uiFlags
, &pptxt
->rcl
, pptxt
->lpstr
, pptxt
->n
, pptxt
->pdx
))
2222 /* FIXME: all following APIs ******************************************/
2225 /***********************************************************************
2226 * SetMapperFlags (GDI32.@)
2228 DWORD WINAPI
SetMapperFlags( HDC hDC
, DWORD dwFlag
)
2230 DC
*dc
= DC_GetDCPtr( hDC
);
2233 if(dc
->funcs
->pSetMapperFlags
)
2235 ret
= dc
->funcs
->pSetMapperFlags( dc
->physDev
, dwFlag
);
2236 /* FIXME: ret is just a success flag, we should return a proper value */
2239 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC
, dwFlag
);
2240 GDI_ReleaseObj( hDC
);
2244 /***********************************************************************
2245 * GetAspectRatioFilterEx (GDI.486)
2247 BOOL16 WINAPI
GetAspectRatioFilterEx16( HDC16 hdc
, LPSIZE16 pAspectRatio
)
2249 FIXME("(%04x, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
2253 /***********************************************************************
2254 * GetAspectRatioFilterEx (GDI32.@)
2256 BOOL WINAPI
GetAspectRatioFilterEx( HDC hdc
, LPSIZE pAspectRatio
)
2258 FIXME("(%p, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
2263 /***********************************************************************
2264 * GetCharABCWidthsA (GDI32.@)
2266 * See GetCharABCWidthsW.
2268 BOOL WINAPI
GetCharABCWidthsA(HDC hdc
, UINT firstChar
, UINT lastChar
,
2271 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
2276 if(count
<= 0) return FALSE
;
2278 str
= HeapAlloc(GetProcessHeap(), 0, count
);
2279 for(i
= 0; i
< count
; i
++)
2280 str
[i
] = (BYTE
)(firstChar
+ i
);
2282 wstr
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
2284 for(i
= 0; i
< wlen
; i
++)
2286 if(!GetCharABCWidthsW(hdc
, wstr
[i
], wstr
[i
], abc
))
2294 HeapFree(GetProcessHeap(), 0, str
);
2295 HeapFree(GetProcessHeap(), 0, wstr
);
2301 /******************************************************************************
2302 * GetCharABCWidthsW [GDI32.@]
2304 * Retrieves widths of characters in range.
2307 * hdc [I] Handle of device context
2308 * firstChar [I] First character in range to query
2309 * lastChar [I] Last character in range to query
2310 * abc [O] Address of character-width structure
2313 * Only works with TrueType fonts
2319 BOOL WINAPI
GetCharABCWidthsW( HDC hdc
, UINT firstChar
, UINT lastChar
,
2322 DC
*dc
= DC_GetDCPtr(hdc
);
2327 ret
= WineEngGetCharABCWidths( dc
->gdiFont
, firstChar
, lastChar
, abc
);
2333 /* convert device units to logical */
2334 for( i
= firstChar
; i
<= lastChar
; i
++, abc
++ ) {
2335 abc
->abcA
= INTERNAL_XDSTOWS(dc
, abc
->abcA
);
2336 abc
->abcB
= INTERNAL_XDSTOWS(dc
, abc
->abcB
);
2337 abc
->abcC
= INTERNAL_XDSTOWS(dc
, abc
->abcC
);
2342 GDI_ReleaseObj(hdc
);
2347 /***********************************************************************
2348 * GetGlyphOutlineA (GDI32.@)
2350 DWORD WINAPI
GetGlyphOutlineA( HDC hdc
, UINT uChar
, UINT fuFormat
,
2351 LPGLYPHMETRICS lpgm
, DWORD cbBuffer
,
2352 LPVOID lpBuffer
, const MAT2
*lpmat2
)
2358 if(!(fuFormat
& GGO_GLYPH_INDEX
)) {
2361 if(uChar
> 0xff) { /* but, 2 bytes character only */
2363 mbchs
[0] = (uChar
& 0xff00) >> 8;
2364 mbchs
[1] = (uChar
& 0xff);
2367 mbchs
[0] = (uChar
& 0xff);
2369 p
= FONT_mbtowc(hdc
, mbchs
, len
, NULL
, NULL
);
2373 ret
= GetGlyphOutlineW(hdc
, c
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
,
2375 HeapFree(GetProcessHeap(), 0, p
);
2379 /***********************************************************************
2380 * GetGlyphOutlineW (GDI32.@)
2382 DWORD WINAPI
GetGlyphOutlineW( HDC hdc
, UINT uChar
, UINT fuFormat
,
2383 LPGLYPHMETRICS lpgm
, DWORD cbBuffer
,
2384 LPVOID lpBuffer
, const MAT2
*lpmat2
)
2386 DC
*dc
= DC_GetDCPtr(hdc
);
2389 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
2390 hdc
, uChar
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
, lpmat2
);
2392 if(!dc
) return GDI_ERROR
;
2395 ret
= WineEngGetGlyphOutline(dc
->gdiFont
, uChar
, fuFormat
, lpgm
,
2396 cbBuffer
, lpBuffer
, lpmat2
);
2400 GDI_ReleaseObj(hdc
);
2405 /***********************************************************************
2406 * CreateScalableFontResourceA (GDI32.@)
2408 BOOL WINAPI
CreateScalableFontResourceA( DWORD fHidden
,
2409 LPCSTR lpszResourceFile
,
2410 LPCSTR lpszFontFile
,
2411 LPCSTR lpszCurrentPath
)
2415 /* fHidden=1 - only visible for the calling app, read-only, not
2416 * enumbered with EnumFonts/EnumFontFamilies
2417 * lpszCurrentPath can be NULL
2419 FIXME("(%ld,%s,%s,%s): stub\n",
2420 fHidden
, debugstr_a(lpszResourceFile
), debugstr_a(lpszFontFile
),
2421 debugstr_a(lpszCurrentPath
) );
2423 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
2424 if ((f
= CreateFileA(lpszResourceFile
, 0, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0)) != INVALID_HANDLE_VALUE
) {
2426 SetLastError(ERROR_FILE_EXISTS
);
2429 return FALSE
; /* create failed */
2432 /***********************************************************************
2433 * CreateScalableFontResourceW (GDI32.@)
2435 BOOL WINAPI
CreateScalableFontResourceW( DWORD fHidden
,
2436 LPCWSTR lpszResourceFile
,
2437 LPCWSTR lpszFontFile
,
2438 LPCWSTR lpszCurrentPath
)
2440 FIXME("(%ld,%p,%p,%p): stub\n",
2441 fHidden
, lpszResourceFile
, lpszFontFile
, lpszCurrentPath
);
2442 return FALSE
; /* create failed */
2445 /*************************************************************************
2446 * GetKerningPairsA (GDI32.@)
2448 DWORD WINAPI
GetKerningPairsA( HDC hDC
, DWORD cPairs
,
2449 LPKERNINGPAIR lpKerningPairs
)
2451 return GetKerningPairsW( hDC
, cPairs
, lpKerningPairs
);
2455 /*************************************************************************
2456 * GetKerningPairsW (GDI32.@)
2458 DWORD WINAPI
GetKerningPairsW( HDC hDC
, DWORD cPairs
,
2459 LPKERNINGPAIR lpKerningPairs
)
2462 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC
, cPairs
, lpKerningPairs
);
2463 for (i
= 0; i
< cPairs
; i
++)
2464 lpKerningPairs
[i
].iKernAmount
= 0;
2468 /*************************************************************************
2469 * TranslateCharsetInfo [GDI32.@]
2471 * Fills a CHARSETINFO structure for a character set, code page, or
2472 * font. This allows making the correspondance between different labelings
2473 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2474 * of the same encoding.
2476 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2477 * only one codepage should be set in *lpSrc.
2480 * TRUE on success, FALSE on failure.
2483 BOOL WINAPI
TranslateCharsetInfo(
2484 LPDWORD lpSrc
, /* [in]
2485 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2486 if flags == TCI_SRCCHARSET: a character set value
2487 if flags == TCI_SRCCODEPAGE: a code page value
2489 LPCHARSETINFO lpCs
, /* [out] structure to receive charset information */
2490 DWORD flags
/* [in] determines interpretation of lpSrc */)
2494 case TCI_SRCFONTSIG
:
2495 while (!(*lpSrc
>>index
& 0x0001) && index
<MAXTCIINDEX
) index
++;
2497 case TCI_SRCCODEPAGE
:
2498 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciACP
&& index
< MAXTCIINDEX
) index
++;
2500 case TCI_SRCCHARSET
:
2501 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciCharset
&& index
< MAXTCIINDEX
) index
++;
2506 if (index
>= MAXTCIINDEX
|| FONT_tci
[index
].ciCharset
== DEFAULT_CHARSET
) return FALSE
;
2507 memcpy(lpCs
, &FONT_tci
[index
], sizeof(CHARSETINFO
));
2511 /*************************************************************************
2512 * GetFontLanguageInfo (GDI32.@)
2514 DWORD WINAPI
GetFontLanguageInfo(HDC hdc
)
2516 FONTSIGNATURE fontsig
;
2517 static const DWORD GCP_DBCS_MASK
=0x003F0000,
2518 GCP_DIACRITIC_MASK
=0x00000000,
2519 FLI_GLYPHS_MASK
=0x00000000,
2520 GCP_GLYPHSHAPE_MASK
=0x00000040,
2521 GCP_KASHIDA_MASK
=0x00000000,
2522 GCP_LIGATE_MASK
=0x00000000,
2523 GCP_USEKERNING_MASK
=0x00000000,
2524 GCP_REORDER_MASK
=0x00000060;
2528 GetTextCharsetInfo( hdc
, &fontsig
, 0 );
2529 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
2531 if( (fontsig
.fsCsb
[0]&GCP_DBCS_MASK
)!=0 )
2534 if( (fontsig
.fsCsb
[0]&GCP_DIACRITIC_MASK
)!=0 )
2535 result
|=GCP_DIACRITIC
;
2537 if( (fontsig
.fsCsb
[0]&FLI_GLYPHS_MASK
)!=0 )
2540 if( (fontsig
.fsCsb
[0]&GCP_GLYPHSHAPE_MASK
)!=0 )
2541 result
|=GCP_GLYPHSHAPE
;
2543 if( (fontsig
.fsCsb
[0]&GCP_KASHIDA_MASK
)!=0 )
2544 result
|=GCP_KASHIDA
;
2546 if( (fontsig
.fsCsb
[0]&GCP_LIGATE_MASK
)!=0 )
2549 if( (fontsig
.fsCsb
[0]&GCP_USEKERNING_MASK
)!=0 )
2550 result
|=GCP_USEKERNING
;
2552 /* this might need a test for a HEBREW- or ARABIC_CHARSET as well */
2553 if( GetTextAlign( hdc
) & TA_RTLREADING
)
2554 if( (fontsig
.fsCsb
[0]&GCP_REORDER_MASK
)!=0 )
2555 result
|=GCP_REORDER
;
2561 /*************************************************************************
2562 * GetFontData [GDI32.@]
2564 * Retrieve data for TrueType font.
2568 * success: Number of bytes returned
2569 * failure: GDI_ERROR
2573 * Calls SetLastError()
2576 DWORD WINAPI
GetFontData(HDC hdc
, DWORD table
, DWORD offset
,
2577 LPVOID buffer
, DWORD length
)
2579 DC
*dc
= DC_GetDCPtr(hdc
);
2580 DWORD ret
= GDI_ERROR
;
2582 if(!dc
) return GDI_ERROR
;
2585 ret
= WineEngGetFontData(dc
->gdiFont
, table
, offset
, buffer
, length
);
2587 GDI_ReleaseObj(hdc
);
2591 /*************************************************************************
2592 * GetGlyphIndicesA [GDI32.@]
2594 DWORD WINAPI
GetGlyphIndicesA(HDC hdc
, LPCSTR lpstr
, INT count
,
2595 LPWORD pgi
, DWORD flags
)
2601 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
2602 hdc
, debugstr_an(lpstr
, count
), count
, pgi
, flags
);
2604 lpstrW
= FONT_mbtowc(hdc
, lpstr
, count
, &countW
, NULL
);
2605 ret
= GetGlyphIndicesW(hdc
, lpstrW
, countW
, pgi
, flags
);
2606 HeapFree(GetProcessHeap(), 0, lpstrW
);
2611 /*************************************************************************
2612 * GetGlyphIndicesW [GDI32.@]
2614 DWORD WINAPI
GetGlyphIndicesW(HDC hdc
, LPCWSTR lpstr
, INT count
,
2615 LPWORD pgi
, DWORD flags
)
2617 DC
*dc
= DC_GetDCPtr(hdc
);
2618 DWORD ret
= GDI_ERROR
;
2620 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
2621 hdc
, debugstr_wn(lpstr
, count
), count
, pgi
, flags
);
2623 if(!dc
) return GDI_ERROR
;
2626 ret
= WineEngGetGlyphIndices(dc
->gdiFont
, lpstr
, count
, pgi
, flags
);
2628 GDI_ReleaseObj(hdc
);
2632 /*************************************************************************
2633 * GetCharacterPlacementA [GDI32.@]
2635 * See GetCharacterPlacementW.
2638 * the web browser control of ie4 calls this with dwFlags=0
2641 GetCharacterPlacementA(HDC hdc
, LPCSTR lpString
, INT uCount
,
2642 INT nMaxExtent
, GCP_RESULTSA
*lpResults
,
2647 GCP_RESULTSW resultsW
;
2651 TRACE("%s, %d, %d, 0x%08lx\n",
2652 debugstr_an(lpString
, uCount
), uCount
, nMaxExtent
, dwFlags
);
2654 /* both structs are equal in size */
2655 memcpy(&resultsW
, lpResults
, sizeof(resultsW
));
2657 lpStringW
= FONT_mbtowc(hdc
, lpString
, uCount
, &uCountW
, &font_cp
);
2658 if(lpResults
->lpOutString
)
2659 resultsW
.lpOutString
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*uCountW
);
2661 ret
= GetCharacterPlacementW(hdc
, lpStringW
, uCountW
, nMaxExtent
, &resultsW
, dwFlags
);
2663 if(lpResults
->lpOutString
) {
2664 WideCharToMultiByte(font_cp
, 0, resultsW
.lpOutString
, uCountW
,
2665 lpResults
->lpOutString
, uCount
, NULL
, NULL
);
2668 HeapFree(GetProcessHeap(), 0, lpStringW
);
2669 HeapFree(GetProcessHeap(), 0, resultsW
.lpOutString
);
2674 /*************************************************************************
2675 * GetCharacterPlacementW [GDI32.@]
2677 * Retrieve information about a string. This includes the width, reordering,
2678 * Glyphing and so on.
2682 * The width and height of the string if successful, 0 if failed.
2686 * All flags except GCP_REORDER are not yet implemented.
2687 * Reordering is not 100% complient to the Windows BiDi method.
2688 * Caret positioning is not yet implemented for BiDi.
2689 * Classes are not yet implemented.
2693 GetCharacterPlacementW(
2694 HDC hdc
, /* [in] Device context for which the rendering is to be done */
2695 LPCWSTR lpString
, /* [in] The string for which information is to be returned */
2696 INT uCount
, /* [in] Number of WORDS in string. */
2697 INT nMaxExtent
, /* [in] Maximum extent the string is to take (in HDC logical units) */
2698 GCP_RESULTSW
*lpResults
,/* [in/out] A pointer to a GCP_RESULTSW struct */
2699 DWORD dwFlags
/* [in] Flags specifying how to process the string */
2706 TRACE("%s, %d, %d, 0x%08lx\n",
2707 debugstr_wn(lpString
, uCount
), uCount
, nMaxExtent
, dwFlags
);
2709 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2710 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2711 lpResults
->lStructSize
, lpResults
->lpOutString
, lpResults
->lpOrder
,
2712 lpResults
->lpDx
, lpResults
->lpCaretPos
, lpResults
->lpClass
,
2713 lpResults
->lpGlyphs
, lpResults
->nGlyphs
, lpResults
->nMaxFit
);
2715 if(dwFlags
&(~GCP_REORDER
)) FIXME("flags 0x%08lx ignored\n", dwFlags
);
2716 if(lpResults
->lpClass
) FIXME("classes not implemented\n");
2717 if (lpResults
->lpCaretPos
&& (dwFlags
& GCP_REORDER
))
2718 FIXME("Caret positions for complex scripts not implemented\n");
2720 nSet
= (UINT
)uCount
;
2721 if(nSet
> lpResults
->nGlyphs
)
2722 nSet
= lpResults
->nGlyphs
;
2724 /* return number of initialized fields */
2725 lpResults
->nGlyphs
= nSet
;
2727 if((dwFlags
&GCP_REORDER
)==0 || !BidiAvail
)
2729 /* Treat the case where no special handling was requested in a fastpath way */
2730 /* copy will do if the GCP_REORDER flag is not set */
2731 if(lpResults
->lpOutString
)
2732 memcpy( lpResults
->lpOutString
, lpString
, nSet
* sizeof(WCHAR
));
2734 if(lpResults
->lpOrder
)
2736 for(i
= 0; i
< nSet
; i
++)
2737 lpResults
->lpOrder
[i
] = i
;
2741 BIDI_Reorder( lpString
, uCount
, dwFlags
, WINE_GCPW_FORCE_LTR
, lpResults
->lpOutString
,
2742 nSet
, lpResults
->lpOrder
);
2745 /* FIXME: Will use the placement chars */
2746 if (lpResults
->lpDx
)
2749 for (i
= 0; i
< nSet
; i
++)
2751 if (GetCharWidth32W(hdc
, lpString
[i
], lpString
[i
], &c
))
2752 lpResults
->lpDx
[i
]= c
;
2756 if (lpResults
->lpCaretPos
&& !(dwFlags
& GCP_REORDER
))
2760 lpResults
->lpCaretPos
[0] = 0;
2761 for (i
= 1; i
< nSet
; i
++)
2762 if (GetTextExtentPoint32W(hdc
, &(lpString
[i
- 1]), 1, &size
))
2763 lpResults
->lpCaretPos
[i
] = (pos
+= size
.cx
);
2766 if(lpResults
->lpGlyphs
)
2767 GetGlyphIndicesW(hdc
, lpString
, nSet
, lpResults
->lpGlyphs
, 0);
2769 if (GetTextExtentPoint32W(hdc
, lpString
, uCount
, &size
))
2770 ret
= MAKELONG(size
.cx
, size
.cy
);
2775 /*************************************************************************
2776 * GetCharABCWidthsFloatA [GDI32.@]
2778 BOOL WINAPI
GetCharABCWidthsFloatA(HDC hdc
, UINT iFirstChar
, UINT iLastChar
,
2781 FIXME_(gdi
)("GetCharABCWidthsFloatA, stub\n");
2785 /*************************************************************************
2786 * GetCharABCWidthsFloatW [GDI32.@]
2788 BOOL WINAPI
GetCharABCWidthsFloatW(HDC hdc
, UINT iFirstChar
,
2789 UINT iLastChar
, LPABCFLOAT lpABCF
)
2791 FIXME_(gdi
)("GetCharABCWidthsFloatW, stub\n");
2795 /*************************************************************************
2796 * GetCharWidthFloatA [GDI32.@]
2798 BOOL WINAPI
GetCharWidthFloatA(HDC hdc
, UINT iFirstChar
,
2799 UINT iLastChar
, PFLOAT pxBuffer
)
2801 FIXME_(gdi
)("GetCharWidthFloatA, stub\n");
2805 /*************************************************************************
2806 * GetCharWidthFloatW [GDI32.@]
2808 BOOL WINAPI
GetCharWidthFloatW(HDC hdc
, UINT iFirstChar
,
2809 UINT iLastChar
, PFLOAT pxBuffer
)
2811 FIXME_(gdi
)("GetCharWidthFloatW, stub\n");
2816 /***********************************************************************
2818 * Font Resource API *
2820 ***********************************************************************/
2822 /***********************************************************************
2823 * AddFontResourceA (GDI32.@)
2825 INT WINAPI
AddFontResourceA( LPCSTR str
)
2827 return AddFontResourceExA( str
, 0, NULL
);
2830 /***********************************************************************
2831 * AddFontResourceW (GDI32.@)
2833 INT WINAPI
AddFontResourceW( LPCWSTR str
)
2835 return AddFontResourceExW(str
, 0, NULL
);
2839 /***********************************************************************
2840 * AddFontResourceExA (GDI32.@)
2842 INT WINAPI
AddFontResourceExA( LPCSTR str
, DWORD fl
, PVOID pdv
)
2844 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
2845 LPWSTR strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2848 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2849 ret
= AddFontResourceExW(strW
, fl
, pdv
);
2850 HeapFree(GetProcessHeap(), 0, strW
);
2854 /***********************************************************************
2855 * AddFontResourceExW (GDI32.@)
2857 INT WINAPI
AddFontResourceExW( LPCWSTR str
, DWORD fl
, PVOID pdv
)
2859 return WineEngAddFontResourceEx(str
, fl
, pdv
);
2862 /***********************************************************************
2863 * RemoveFontResourceA (GDI32.@)
2865 BOOL WINAPI
RemoveFontResourceA( LPCSTR str
)
2867 return RemoveFontResourceExA(str
, 0, 0);
2870 /***********************************************************************
2871 * RemoveFontResourceW (GDI32.@)
2873 BOOL WINAPI
RemoveFontResourceW( LPCWSTR str
)
2875 return RemoveFontResourceExW(str
, 0, 0);
2878 /***********************************************************************
2879 * RemoveFontResourceExA (GDI32.@)
2881 BOOL WINAPI
RemoveFontResourceExA( LPCSTR str
, DWORD fl
, PVOID pdv
)
2883 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
2884 LPWSTR strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2887 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2888 ret
= RemoveFontResourceExW(strW
, fl
, pdv
);
2889 HeapFree(GetProcessHeap(), 0, strW
);
2893 /***********************************************************************
2894 * RemoveFontResourceExW (GDI32.@)
2896 BOOL WINAPI
RemoveFontResourceExW( LPCWSTR str
, DWORD fl
, PVOID pdv
)
2898 return WineEngRemoveFontResourceEx(str
, fl
, pdv
);
2901 /***********************************************************************
2902 * GetTextCharset (GDI32.@)
2904 UINT WINAPI
GetTextCharset(HDC hdc
)
2906 /* MSDN docs say this is equivalent */
2907 return GetTextCharsetInfo(hdc
, NULL
, 0);
2910 /***********************************************************************
2911 * GetTextCharsetInfo (GDI32.@)
2913 UINT WINAPI
GetTextCharsetInfo(HDC hdc
, LPFONTSIGNATURE fs
, DWORD flags
)
2915 UINT ret
= DEFAULT_CHARSET
;
2916 DC
*dc
= DC_GetDCPtr(hdc
);
2921 ret
= WineEngGetTextCharsetInfo(dc
->gdiFont
, fs
, flags
);
2923 GDI_ReleaseObj(hdc
);
2926 if (ret
== DEFAULT_CHARSET
&& fs
)
2927 memset(fs
, 0, sizeof(FONTSIGNATURE
));
2931 /***********************************************************************
2932 * GdiGetCharDimensions (GDI32.@)
2934 * Gets the average width of the characters in the English alphabet.
2937 * hdc [I] Handle to the device context to measure on.
2938 * lptm [O] Pointer to memory to store the text metrics into.
2939 * height [O] On exit, the maximum height of characters in the English alphabet.
2942 * The average width of characters in the English alphabet.
2945 * This function is used by the dialog manager to get the size of a dialog
2946 * unit. It should also be used by other pieces of code that need to know
2947 * the size of a dialog unit in logical units without having access to the
2948 * window handle of the dialog.
2949 * Windows caches the font metrics from this function, but we don't and
2950 * there doesn't appear to be an immediate advantage to do so.
2953 * GetTextExtentPointW, GetTextMetricsW, MapDialogRect.
2955 LONG WINAPI
GdiGetCharDimensions(HDC hdc
, LPTEXTMETRICW lptm
, LONG
*height
)
2958 static const WCHAR alphabet
[] = {
2959 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
2960 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
2961 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
2963 if(lptm
&& !GetTextMetricsW(hdc
, lptm
)) return 0;
2965 if(!GetTextExtentPointW(hdc
, alphabet
, 52, &sz
)) return 0;
2967 if (height
) *height
= sz
.cy
;
2968 return (sz
.cx
/ 26 + 1) / 2;
2971 BOOL WINAPI
EnableEUDC(BOOL fEnableEUDC
)
2973 FIXME("(%d): stub\n", fEnableEUDC
);