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 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
,
218 static void FONT_LogFontWToA( const LOGFONTW
*fontW
, LPLOGFONTA fontA
)
220 memcpy(fontA
, fontW
, sizeof(LOGFONTA
) - LF_FACESIZE
);
221 WideCharToMultiByte(CP_ACP
, 0, fontW
->lfFaceName
, -1, fontA
->lfFaceName
,
222 LF_FACESIZE
, NULL
, NULL
);
225 static void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW
*fontW
, LPENUMLOGFONTEX16 font16
)
227 FONT_LogFontWTo16( (LPLOGFONTW
)fontW
, (LPLOGFONT16
)font16
);
229 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfFullName
, -1,
230 font16
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
231 font16
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
232 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfStyle
, -1,
233 font16
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
234 font16
->elfStyle
[LF_FACESIZE
-1] = '\0';
235 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfScript
, -1,
236 font16
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
237 font16
->elfScript
[LF_FACESIZE
-1] = '\0';
240 static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW
*fontW
, LPENUMLOGFONTEXA fontA
)
242 FONT_LogFontWToA( (LPLOGFONTW
)fontW
, (LPLOGFONTA
)fontA
);
244 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfFullName
, -1,
245 fontA
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
246 fontA
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
247 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfStyle
, -1,
248 fontA
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
249 fontA
->elfStyle
[LF_FACESIZE
-1] = '\0';
250 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfScript
, -1,
251 fontA
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
252 fontA
->elfScript
[LF_FACESIZE
-1] = '\0';
255 /***********************************************************************
256 * TEXTMETRIC conversion functions.
258 static void FONT_TextMetricWToA(const TEXTMETRICW
*ptmW
, LPTEXTMETRICA ptmA
)
260 ptmA
->tmHeight
= ptmW
->tmHeight
;
261 ptmA
->tmAscent
= ptmW
->tmAscent
;
262 ptmA
->tmDescent
= ptmW
->tmDescent
;
263 ptmA
->tmInternalLeading
= ptmW
->tmInternalLeading
;
264 ptmA
->tmExternalLeading
= ptmW
->tmExternalLeading
;
265 ptmA
->tmAveCharWidth
= ptmW
->tmAveCharWidth
;
266 ptmA
->tmMaxCharWidth
= ptmW
->tmMaxCharWidth
;
267 ptmA
->tmWeight
= ptmW
->tmWeight
;
268 ptmA
->tmOverhang
= ptmW
->tmOverhang
;
269 ptmA
->tmDigitizedAspectX
= ptmW
->tmDigitizedAspectX
;
270 ptmA
->tmDigitizedAspectY
= ptmW
->tmDigitizedAspectY
;
271 ptmA
->tmFirstChar
= ptmW
->tmFirstChar
> 255 ? 255 : ptmW
->tmFirstChar
;
272 ptmA
->tmLastChar
= ptmW
->tmLastChar
> 255 ? 255 : ptmW
->tmLastChar
;
273 ptmA
->tmDefaultChar
= ptmW
->tmDefaultChar
> 255 ? 255 : ptmW
->tmDefaultChar
;
274 ptmA
->tmBreakChar
= ptmW
->tmBreakChar
> 255 ? 255 : ptmW
->tmBreakChar
;
275 ptmA
->tmItalic
= ptmW
->tmItalic
;
276 ptmA
->tmUnderlined
= ptmW
->tmUnderlined
;
277 ptmA
->tmStruckOut
= ptmW
->tmStruckOut
;
278 ptmA
->tmPitchAndFamily
= ptmW
->tmPitchAndFamily
;
279 ptmA
->tmCharSet
= ptmW
->tmCharSet
;
283 static void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW
*ptmW
, LPNEWTEXTMETRICEX16 ptm16
)
285 ptm16
->ntmTm
.tmHeight
= ptmW
->ntmTm
.tmHeight
;
286 ptm16
->ntmTm
.tmAscent
= ptmW
->ntmTm
.tmAscent
;
287 ptm16
->ntmTm
.tmDescent
= ptmW
->ntmTm
.tmDescent
;
288 ptm16
->ntmTm
.tmInternalLeading
= ptmW
->ntmTm
.tmInternalLeading
;
289 ptm16
->ntmTm
.tmExternalLeading
= ptmW
->ntmTm
.tmExternalLeading
;
290 ptm16
->ntmTm
.tmAveCharWidth
= ptmW
->ntmTm
.tmAveCharWidth
;
291 ptm16
->ntmTm
.tmMaxCharWidth
= ptmW
->ntmTm
.tmMaxCharWidth
;
292 ptm16
->ntmTm
.tmWeight
= ptmW
->ntmTm
.tmWeight
;
293 ptm16
->ntmTm
.tmOverhang
= ptmW
->ntmTm
.tmOverhang
;
294 ptm16
->ntmTm
.tmDigitizedAspectX
= ptmW
->ntmTm
.tmDigitizedAspectX
;
295 ptm16
->ntmTm
.tmDigitizedAspectY
= ptmW
->ntmTm
.tmDigitizedAspectY
;
296 ptm16
->ntmTm
.tmFirstChar
= ptmW
->ntmTm
.tmFirstChar
> 255 ? 255 : ptmW
->ntmTm
.tmFirstChar
;
297 ptm16
->ntmTm
.tmLastChar
= ptmW
->ntmTm
.tmLastChar
> 255 ? 255 : ptmW
->ntmTm
.tmLastChar
;
298 ptm16
->ntmTm
.tmDefaultChar
= ptmW
->ntmTm
.tmDefaultChar
> 255 ? 255 : ptmW
->ntmTm
.tmDefaultChar
;
299 ptm16
->ntmTm
.tmBreakChar
= ptmW
->ntmTm
.tmBreakChar
> 255 ? 255 : ptmW
->ntmTm
.tmBreakChar
;
300 ptm16
->ntmTm
.tmItalic
= ptmW
->ntmTm
.tmItalic
;
301 ptm16
->ntmTm
.tmUnderlined
= ptmW
->ntmTm
.tmUnderlined
;
302 ptm16
->ntmTm
.tmStruckOut
= ptmW
->ntmTm
.tmStruckOut
;
303 ptm16
->ntmTm
.tmPitchAndFamily
= ptmW
->ntmTm
.tmPitchAndFamily
;
304 ptm16
->ntmTm
.tmCharSet
= ptmW
->ntmTm
.tmCharSet
;
305 ptm16
->ntmTm
.ntmFlags
= ptmW
->ntmTm
.ntmFlags
;
306 ptm16
->ntmTm
.ntmSizeEM
= ptmW
->ntmTm
.ntmSizeEM
;
307 ptm16
->ntmTm
.ntmCellHeight
= ptmW
->ntmTm
.ntmCellHeight
;
308 ptm16
->ntmTm
.ntmAvgWidth
= ptmW
->ntmTm
.ntmAvgWidth
;
309 memcpy(&ptm16
->ntmFontSig
, &ptmW
->ntmFontSig
, sizeof(FONTSIGNATURE
));
312 static void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW
*ptmW
, NEWTEXTMETRICEXA
*ptmA
)
314 FONT_TextMetricWToA((LPTEXTMETRICW
)ptmW
, (LPTEXTMETRICA
)ptmA
);
315 ptmA
->ntmTm
.ntmFlags
= ptmW
->ntmTm
.ntmFlags
;
316 ptmA
->ntmTm
.ntmSizeEM
= ptmW
->ntmTm
.ntmSizeEM
;
317 ptmA
->ntmTm
.ntmCellHeight
= ptmW
->ntmTm
.ntmCellHeight
;
318 ptmA
->ntmTm
.ntmAvgWidth
= ptmW
->ntmTm
.ntmAvgWidth
;
319 memcpy(&ptmA
->ntmFontSig
, &ptmW
->ntmFontSig
, sizeof(FONTSIGNATURE
));
322 /***********************************************************************
323 * CreateFontIndirectA (GDI32.@)
325 HFONT WINAPI
CreateFontIndirectA( const LOGFONTA
*plfA
)
330 FONT_LogFontAToW( plfA
, &lfW
);
331 return CreateFontIndirectW( &lfW
);
333 return CreateFontIndirectW( NULL
);
337 /***********************************************************************
338 * CreateFontIndirectW (GDI32.@)
340 HFONT WINAPI
CreateFontIndirectW( const LOGFONTW
*plf
)
347 if ((fontPtr
= GDI_AllocObject( sizeof(FONTOBJ
), FONT_MAGIC
,
348 (HGDIOBJ
*)&hFont
, &font_funcs
)))
350 static const WCHAR ItalicW
[] = {' ','I','t','a','l','i','c','\0'};
351 static const WCHAR BoldW
[] = {' ','B','o','l','d','\0'};
352 WCHAR
*pFaceNameItalicSuffix
, *pFaceNameBoldSuffix
;
353 WCHAR
* pFaceNameSuffix
= NULL
;
355 memcpy( &fontPtr
->logfont
, plf
, sizeof(LOGFONTW
) );
357 TRACE("(%ld %ld %ld %ld %x %d %x %d %d) %s %s %s %s => %p\n",
358 plf
->lfHeight
, plf
->lfWidth
,
359 plf
->lfEscapement
, plf
->lfOrientation
,
360 plf
->lfPitchAndFamily
,
361 plf
->lfOutPrecision
, plf
->lfClipPrecision
,
362 plf
->lfQuality
, plf
->lfCharSet
,
363 debugstr_w(plf
->lfFaceName
),
364 plf
->lfWeight
> 400 ? "Bold" : "",
365 plf
->lfItalic
? "Italic" : "",
366 plf
->lfUnderline
? "Underline" : "", hFont
);
368 if (plf
->lfEscapement
!= plf
->lfOrientation
) {
369 /* this should really depend on whether GM_ADVANCED is set */
370 fontPtr
->logfont
.lfOrientation
= fontPtr
->logfont
.lfEscapement
;
371 WARN("orientation angle %f set to "
372 "escapement angle %f for new font %p\n",
373 plf
->lfOrientation
/10., plf
->lfEscapement
/10., hFont
);
376 pFaceNameItalicSuffix
= strstrW(fontPtr
->logfont
.lfFaceName
, ItalicW
);
377 if (pFaceNameItalicSuffix
) {
378 fontPtr
->logfont
.lfItalic
= TRUE
;
379 pFaceNameSuffix
= pFaceNameItalicSuffix
;
382 pFaceNameBoldSuffix
= strstrW(fontPtr
->logfont
.lfFaceName
, BoldW
);
383 if (pFaceNameBoldSuffix
) {
384 if (fontPtr
->logfont
.lfWeight
< FW_BOLD
) {
385 fontPtr
->logfont
.lfWeight
= FW_BOLD
;
387 if (!pFaceNameSuffix
||
388 (pFaceNameBoldSuffix
< pFaceNameSuffix
)) {
389 pFaceNameSuffix
= pFaceNameBoldSuffix
;
393 if (pFaceNameSuffix
) *pFaceNameSuffix
= 0;
395 GDI_ReleaseObj( hFont
);
398 else WARN("(NULL) => NULL\n");
403 /*************************************************************************
404 * CreateFontA (GDI32.@)
406 HFONT WINAPI
CreateFontA( INT height
, INT width
, INT esc
,
407 INT orient
, INT weight
, DWORD italic
,
408 DWORD underline
, DWORD strikeout
, DWORD charset
,
409 DWORD outpres
, DWORD clippres
, DWORD quality
,
410 DWORD pitch
, LPCSTR name
)
414 logfont
.lfHeight
= height
;
415 logfont
.lfWidth
= width
;
416 logfont
.lfEscapement
= esc
;
417 logfont
.lfOrientation
= orient
;
418 logfont
.lfWeight
= weight
;
419 logfont
.lfItalic
= italic
;
420 logfont
.lfUnderline
= underline
;
421 logfont
.lfStrikeOut
= strikeout
;
422 logfont
.lfCharSet
= charset
;
423 logfont
.lfOutPrecision
= outpres
;
424 logfont
.lfClipPrecision
= clippres
;
425 logfont
.lfQuality
= quality
;
426 logfont
.lfPitchAndFamily
= pitch
;
429 lstrcpynA(logfont
.lfFaceName
,name
,sizeof(logfont
.lfFaceName
));
431 logfont
.lfFaceName
[0] = '\0';
433 return CreateFontIndirectA( &logfont
);
436 /*************************************************************************
437 * CreateFontW (GDI32.@)
439 HFONT WINAPI
CreateFontW( INT height
, INT width
, INT esc
,
440 INT orient
, INT weight
, DWORD italic
,
441 DWORD underline
, DWORD strikeout
, DWORD charset
,
442 DWORD outpres
, DWORD clippres
, DWORD quality
,
443 DWORD pitch
, LPCWSTR name
)
447 logfont
.lfHeight
= height
;
448 logfont
.lfWidth
= width
;
449 logfont
.lfEscapement
= esc
;
450 logfont
.lfOrientation
= orient
;
451 logfont
.lfWeight
= weight
;
452 logfont
.lfItalic
= italic
;
453 logfont
.lfUnderline
= underline
;
454 logfont
.lfStrikeOut
= strikeout
;
455 logfont
.lfCharSet
= charset
;
456 logfont
.lfOutPrecision
= outpres
;
457 logfont
.lfClipPrecision
= clippres
;
458 logfont
.lfQuality
= quality
;
459 logfont
.lfPitchAndFamily
= pitch
;
462 lstrcpynW(logfont
.lfFaceName
, name
,
463 sizeof(logfont
.lfFaceName
) / sizeof(WCHAR
));
465 logfont
.lfFaceName
[0] = '\0';
467 return CreateFontIndirectW( &logfont
);
471 /***********************************************************************
474 * If the driver supports vector fonts we create a gdi font first and
475 * then call the driver to give it a chance to supply its own device
476 * font. If the driver wants to do this it returns TRUE and we can
477 * delete the gdi font, if the driver wants to use the gdi font it
478 * should return FALSE, to signal an error return GDI_ERROR. For
479 * drivers that don't support vector fonts they must supply their own
482 static HGDIOBJ
FONT_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
)
485 DC
*dc
= DC_GetDCPtr( hdc
);
489 if (dc
->hFont
!= handle
|| dc
->gdiFont
== NULL
)
491 if(GetDeviceCaps(dc
->hSelf
, TEXTCAPS
) & TC_VA_ABLE
)
492 dc
->gdiFont
= WineEngCreateFontInstance(dc
, handle
);
495 if (dc
->funcs
->pSelectFont
) ret
= dc
->funcs
->pSelectFont( dc
->physDev
, handle
, dc
->gdiFont
);
497 if (ret
&& dc
->gdiFont
) dc
->gdiFont
= 0;
499 if (ret
== HGDI_ERROR
)
500 ret
= 0; /* SelectObject returns 0 on error */
506 GDI_ReleaseObj( hdc
);
511 /***********************************************************************
514 static INT
FONT_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
519 FONT_LogFontWTo16( &font
->logfont
, &lf16
);
521 if (count
> sizeof(LOGFONT16
)) count
= sizeof(LOGFONT16
);
522 memcpy( buffer
, &lf16
, count
);
526 /***********************************************************************
529 static INT
FONT_GetObjectA( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
536 FONT_LogFontWToA( &font
->logfont
, &lfA
);
538 if (count
> sizeof(lfA
)) count
= sizeof(lfA
);
539 memcpy( buffer
, &lfA
, count
);
543 /***********************************************************************
546 static INT
FONT_GetObjectW( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
550 return sizeof(LOGFONTW
);
551 if (count
> sizeof(LOGFONTW
)) count
= sizeof(LOGFONTW
);
552 memcpy( buffer
, &font
->logfont
, count
);
557 /***********************************************************************
560 static BOOL
FONT_DeleteObject( HGDIOBJ handle
, void *obj
)
562 WineEngDestroyFontInstance( handle
);
563 return GDI_FreeObject( handle
, obj
);
567 /***********************************************************************
568 * FONT_EnumInstance16
570 * Called by the device driver layer to pass font info
571 * down to the application.
573 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
574 * We have to use other types because of the FONTENUMPROCW definition.
576 static INT CALLBACK
FONT_EnumInstance16( const LOGFONTW
*plf
, const TEXTMETRICW
*ptm
,
577 DWORD fType
, LPARAM lp
)
579 fontEnum16
*pfe
= (fontEnum16
*)lp
;
583 if( pfe
->lpLogFontParam
->lfCharSet
== DEFAULT_CHARSET
||
584 pfe
->lpLogFontParam
->lfCharSet
== plf
->lfCharSet
)
589 FONT_EnumLogFontExWTo16((const ENUMLOGFONTEXW
*)plf
, pfe
->lpLogFont
);
590 FONT_NewTextMetricExWTo16((const NEWTEXTMETRICEXW
*)ptm
, pfe
->lpTextMetric
);
591 pfe
->dwFlags
|= ENUM_CALLED
;
592 GDI_ReleaseObj( pfe
->hdc
); /* release the GDI lock */
594 args
[6] = SELECTOROF(pfe
->segLogFont
);
595 args
[5] = OFFSETOF(pfe
->segLogFont
);
596 args
[4] = SELECTOROF(pfe
->segTextMetric
);
597 args
[3] = OFFSETOF(pfe
->segTextMetric
);
599 args
[1] = HIWORD(pfe
->lpData
);
600 args
[0] = LOWORD(pfe
->lpData
);
601 WOWCallback16Ex( (DWORD
)pfe
->lpEnumFunc
, WCB16_PASCAL
, sizeof(args
), args
, &result
);
602 ret
= LOWORD(result
);
604 /* get the lock again and make sure the DC is still valid */
605 dc
= DC_GetDCPtr( pfe
->hdc
);
606 if (!dc
|| dc
!= pfe
->dc
|| dc
->physDev
!= pfe
->physDev
)
608 if (dc
) GDI_ReleaseObj( pfe
->hdc
);
609 pfe
->hdc
= 0; /* make sure we don't try to release it later on */
616 /***********************************************************************
619 * Note: plf is really an ENUMLOGFONTEXW, and ptm is a NEWTEXTMETRICEXW.
620 * We have to use other types because of the FONTENUMPROCW definition.
622 static INT CALLBACK
FONT_EnumInstance( const LOGFONTW
*plf
, const TEXTMETRICW
*ptm
,
623 DWORD fType
, LPARAM lp
)
625 fontEnum32
*pfe
= (fontEnum32
*)lp
;
629 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
630 if((pfe
->lpLogFontParam
->lfCharSet
== DEFAULT_CHARSET
||
631 pfe
->lpLogFontParam
->lfCharSet
== plf
->lfCharSet
) &&
632 (!(fType
& RASTER_FONTTYPE
) || GetDeviceCaps(pfe
->hdc
, TEXTCAPS
) & TC_RA_ABLE
) )
634 /* convert font metrics */
635 ENUMLOGFONTEXA logfont
;
636 NEWTEXTMETRICEXA tmA
;
638 pfe
->dwFlags
|= ENUM_CALLED
;
639 if (!(pfe
->dwFlags
& ENUM_UNICODE
))
641 FONT_EnumLogFontExWToA( (const ENUMLOGFONTEXW
*)plf
, &logfont
);
642 FONT_NewTextMetricExWToA( (const NEWTEXTMETRICEXW
*)ptm
, &tmA
);
643 plf
= (LOGFONTW
*)&logfont
.elfLogFont
;
644 ptm
= (TEXTMETRICW
*)&tmA
;
646 GDI_ReleaseObj( pfe
->hdc
); /* release the GDI lock */
648 ret
= pfe
->lpEnumFunc( plf
, ptm
, fType
, pfe
->lpData
);
650 /* get the lock again and make sure the DC is still valid */
651 dc
= DC_GetDCPtr( pfe
->hdc
);
652 if (!dc
|| dc
!= pfe
->dc
|| dc
->physDev
!= pfe
->physDev
)
654 if (dc
) GDI_ReleaseObj( pfe
->hdc
);
655 pfe
->hdc
= 0; /* make sure we don't try to release it later on */
662 /***********************************************************************
663 * EnumFontFamiliesEx (GDI.613)
665 INT16 WINAPI
EnumFontFamiliesEx16( HDC16 hDC
, LPLOGFONT16 plf
,
666 FONTENUMPROC16 efproc
, LPARAM lParam
,
671 DC
* dc
= DC_GetDCPtr( HDC_32(hDC
) );
672 NEWTEXTMETRICEX16 tm16
;
673 ENUMLOGFONTEX16 lf16
;
678 FONT_LogFont16ToW(plf
, &lfW
);
680 fe16
.hdc
= HDC_32(hDC
);
682 fe16
.physDev
= dc
->physDev
;
683 fe16
.lpLogFontParam
= plf
;
684 fe16
.lpEnumFunc
= efproc
;
685 fe16
.lpData
= lParam
;
686 fe16
.lpTextMetric
= &tm16
;
687 fe16
.lpLogFont
= &lf16
;
688 fe16
.segTextMetric
= MapLS( &tm16
);
689 fe16
.segLogFont
= MapLS( &lf16
);
692 enum_gdi_fonts
= GetDeviceCaps(fe16
.hdc
, TEXTCAPS
) & TC_VA_ABLE
;
694 if (!dc
->funcs
->pEnumDeviceFonts
&& !enum_gdi_fonts
)
701 ret
= WineEngEnumFonts( &lfW
, FONT_EnumInstance16
, (LPARAM
)&fe16
);
702 fe16
.dwFlags
&= ~ENUM_CALLED
;
703 if (ret
&& dc
->funcs
->pEnumDeviceFonts
) {
704 ret2
= dc
->funcs
->pEnumDeviceFonts( dc
->physDev
, &lfW
, FONT_EnumInstance16
, (LPARAM
)&fe16
);
705 if(fe16
.dwFlags
& ENUM_CALLED
) /* update ret iff a font gets enumed */
709 UnMapLS( fe16
.segTextMetric
);
710 UnMapLS( fe16
.segLogFont
);
711 if (fe16
.hdc
) GDI_ReleaseObj( fe16
.hdc
);
715 /***********************************************************************
716 * FONT_EnumFontFamiliesEx
718 static INT
FONT_EnumFontFamiliesEx( HDC hDC
, LPLOGFONTW plf
,
719 FONTENUMPROCW efproc
,
720 LPARAM lParam
, DWORD dwUnicode
)
723 DC
*dc
= DC_GetDCPtr( hDC
);
729 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf
->lfFaceName
),
731 fe32
.lpLogFontParam
= plf
;
732 fe32
.lpEnumFunc
= efproc
;
733 fe32
.lpData
= lParam
;
734 fe32
.dwFlags
= dwUnicode
;
737 fe32
.physDev
= dc
->physDev
;
739 enum_gdi_fonts
= GetDeviceCaps(hDC
, TEXTCAPS
) & TC_VA_ABLE
;
741 if (!dc
->funcs
->pEnumDeviceFonts
&& !enum_gdi_fonts
)
748 ret
= WineEngEnumFonts( plf
, FONT_EnumInstance
, (LPARAM
)&fe32
);
749 fe32
.dwFlags
&= ~ENUM_CALLED
;
750 if (ret
&& dc
->funcs
->pEnumDeviceFonts
) {
751 ret2
= dc
->funcs
->pEnumDeviceFonts( dc
->physDev
, plf
, FONT_EnumInstance
, (LPARAM
)&fe32
);
752 if(fe32
.dwFlags
& ENUM_CALLED
) /* update ret iff a font gets enumed */
756 if (fe32
.hdc
) GDI_ReleaseObj( fe32
.hdc
);
760 /***********************************************************************
761 * EnumFontFamiliesExW (GDI32.@)
763 INT WINAPI
EnumFontFamiliesExW( HDC hDC
, LPLOGFONTW plf
,
764 FONTENUMPROCW efproc
,
765 LPARAM lParam
, DWORD dwFlags
)
767 return FONT_EnumFontFamiliesEx( hDC
, plf
, efproc
, lParam
, ENUM_UNICODE
);
770 /***********************************************************************
771 * EnumFontFamiliesExA (GDI32.@)
773 INT WINAPI
EnumFontFamiliesExA( HDC hDC
, LPLOGFONTA plf
,
774 FONTENUMPROCA efproc
,
775 LPARAM lParam
, DWORD dwFlags
)
778 FONT_LogFontAToW( plf
, &lfW
);
780 return FONT_EnumFontFamiliesEx( hDC
, &lfW
, (FONTENUMPROCW
)efproc
, lParam
, 0);
783 /***********************************************************************
784 * EnumFontFamilies (GDI.330)
786 INT16 WINAPI
EnumFontFamilies16( HDC16 hDC
, LPCSTR lpFamily
,
787 FONTENUMPROC16 efproc
, LPARAM lpData
)
791 lf
.lfCharSet
= DEFAULT_CHARSET
;
792 if( lpFamily
) lstrcpynA( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
793 else lf
.lfFaceName
[0] = '\0';
795 return EnumFontFamiliesEx16( hDC
, &lf
, efproc
, lpData
, 0 );
798 /***********************************************************************
799 * EnumFontFamiliesA (GDI32.@)
801 INT WINAPI
EnumFontFamiliesA( HDC hDC
, LPCSTR lpFamily
,
802 FONTENUMPROCA efproc
, LPARAM lpData
)
806 lf
.lfCharSet
= DEFAULT_CHARSET
;
807 if( lpFamily
) lstrcpynA( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
808 else lf
.lfFaceName
[0] = lf
.lfFaceName
[1] = '\0';
810 return EnumFontFamiliesExA( hDC
, &lf
, efproc
, lpData
, 0 );
813 /***********************************************************************
814 * EnumFontFamiliesW (GDI32.@)
816 INT WINAPI
EnumFontFamiliesW( HDC hDC
, LPCWSTR lpFamily
,
817 FONTENUMPROCW efproc
, LPARAM lpData
)
821 lf
.lfCharSet
= DEFAULT_CHARSET
;
822 if( lpFamily
) lstrcpynW( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
823 else lf
.lfFaceName
[0] = 0;
825 return EnumFontFamiliesExW( hDC
, &lf
, efproc
, lpData
, 0 );
828 /***********************************************************************
831 INT16 WINAPI
EnumFonts16( HDC16 hDC
, LPCSTR lpName
, FONTENUMPROC16 efproc
,
834 return EnumFontFamilies16( hDC
, lpName
, efproc
, lpData
);
837 /***********************************************************************
838 * EnumFontsA (GDI32.@)
840 INT WINAPI
EnumFontsA( HDC hDC
, LPCSTR lpName
, FONTENUMPROCA efproc
,
843 return EnumFontFamiliesA( hDC
, lpName
, efproc
, lpData
);
846 /***********************************************************************
847 * EnumFontsW (GDI32.@)
849 INT WINAPI
EnumFontsW( HDC hDC
, LPCWSTR lpName
, FONTENUMPROCW efproc
,
852 return EnumFontFamiliesW( hDC
, lpName
, efproc
, lpData
);
856 /***********************************************************************
857 * GetTextCharacterExtra (GDI32.@)
859 INT WINAPI
GetTextCharacterExtra( HDC hdc
)
862 DC
*dc
= DC_GetDCPtr( hdc
);
863 if (!dc
) return 0x80000000;
865 GDI_ReleaseObj( hdc
);
870 /***********************************************************************
871 * SetTextCharacterExtra (GDI32.@)
873 INT WINAPI
SetTextCharacterExtra( HDC hdc
, INT extra
)
876 DC
* dc
= DC_GetDCPtr( hdc
);
877 if (!dc
) return 0x80000000;
878 if (dc
->funcs
->pSetTextCharacterExtra
)
879 prev
= dc
->funcs
->pSetTextCharacterExtra( dc
->physDev
, extra
);
882 prev
= dc
->charExtra
;
883 dc
->charExtra
= extra
;
885 GDI_ReleaseObj( hdc
);
890 /***********************************************************************
891 * SetTextJustification (GDI32.@)
893 BOOL WINAPI
SetTextJustification( HDC hdc
, INT extra
, INT breaks
)
896 DC
* dc
= DC_GetDCPtr( hdc
);
897 if (!dc
) return FALSE
;
898 if (dc
->funcs
->pSetTextJustification
)
899 ret
= dc
->funcs
->pSetTextJustification( dc
->physDev
, extra
, breaks
);
902 extra
= abs((extra
* dc
->vportExtX
+ dc
->wndExtX
/ 2) / dc
->wndExtX
);
903 if (!extra
) breaks
= 0;
906 dc
->breakExtra
= extra
/ breaks
;
907 dc
->breakRem
= extra
- (breaks
* dc
->breakExtra
);
915 GDI_ReleaseObj( hdc
);
920 /***********************************************************************
921 * GetTextFaceA (GDI32.@)
923 INT WINAPI
GetTextFaceA( HDC hdc
, INT count
, LPSTR name
)
925 INT res
= GetTextFaceW(hdc
, 0, NULL
);
926 LPWSTR nameW
= HeapAlloc( GetProcessHeap(), 0, res
* 2 );
927 GetTextFaceW( hdc
, res
, nameW
);
931 if (count
&& !WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, name
, count
, NULL
, NULL
))
936 res
= WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, NULL
, 0, NULL
, NULL
);
937 HeapFree( GetProcessHeap(), 0, nameW
);
941 /***********************************************************************
942 * GetTextFaceW (GDI32.@)
944 INT WINAPI
GetTextFaceW( HDC hdc
, INT count
, LPWSTR name
)
949 DC
* dc
= DC_GetDCPtr( hdc
);
953 ret
= WineEngGetTextFace(dc
->gdiFont
, count
, name
);
954 else if ((font
= (FONTOBJ
*) GDI_GetObjPtr( dc
->hFont
, FONT_MAGIC
)))
958 lstrcpynW( name
, font
->logfont
.lfFaceName
, count
);
961 else ret
= strlenW(font
->logfont
.lfFaceName
) + 1;
962 GDI_ReleaseObj( dc
->hFont
);
964 GDI_ReleaseObj( hdc
);
969 /***********************************************************************
970 * GetTextExtentPoint32A (GDI32.@)
972 BOOL WINAPI
GetTextExtentPoint32A( HDC hdc
, LPCSTR str
, INT count
,
977 LPWSTR p
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
980 ret
= GetTextExtentPoint32W( hdc
, p
, wlen
, size
);
981 HeapFree( GetProcessHeap(), 0, p
);
984 TRACE("(%p %s %d %p): returning %ld x %ld\n",
985 hdc
, debugstr_an (str
, count
), count
, size
, size
->cx
, size
->cy
);
990 /***********************************************************************
991 * GetTextExtentPoint32W [GDI32.@]
993 * Computes width/height for a string.
995 * Computes width and height of the specified string.
1001 BOOL WINAPI
GetTextExtentPoint32W(
1002 HDC hdc
, /* [in] Handle of device context */
1003 LPCWSTR str
, /* [in] Address of text string */
1004 INT count
, /* [in] Number of characters in string */
1005 LPSIZE size
) /* [out] Address of structure for string size */
1008 DC
* dc
= DC_GetDCPtr( hdc
);
1009 if (!dc
) return FALSE
;
1012 ret
= WineEngGetTextExtentPoint(dc
->gdiFont
, str
, count
, size
);
1013 else if(dc
->funcs
->pGetTextExtentPoint
)
1014 ret
= dc
->funcs
->pGetTextExtentPoint( dc
->physDev
, str
, count
, size
);
1018 size
->cx
= abs(INTERNAL_XDSTOWS(dc
, size
->cx
));
1019 size
->cy
= abs(INTERNAL_YDSTOWS(dc
, size
->cy
));
1020 size
->cx
+= count
* dc
->charExtra
+ dc
->breakRem
;
1023 GDI_ReleaseObj( hdc
);
1025 TRACE("(%p %s %d %p): returning %ld x %ld\n",
1026 hdc
, debugstr_wn (str
, count
), count
, size
, size
->cx
, size
->cy
);
1030 /***********************************************************************
1031 * GetTextExtentPointI [GDI32.@]
1033 * Computes width and height of the array of glyph indices.
1039 BOOL WINAPI
GetTextExtentPointI(
1040 HDC hdc
, /* [in] Handle of device context */
1041 const WORD
*indices
, /* [in] Address of glyph index array */
1042 INT count
, /* [in] Number of glyphs in array */
1043 LPSIZE size
) /* [out] Address of structure for string size */
1046 DC
* dc
= DC_GetDCPtr( hdc
);
1047 if (!dc
) return FALSE
;
1050 ret
= WineEngGetTextExtentPointI(dc
->gdiFont
, indices
, count
, size
);
1051 size
->cx
= abs(INTERNAL_XDSTOWS(dc
, size
->cx
));
1052 size
->cy
= abs(INTERNAL_YDSTOWS(dc
, size
->cy
));
1053 size
->cx
+= count
* dc
->charExtra
;
1055 else if(dc
->funcs
->pGetTextExtentPoint
) {
1056 FIXME("calling GetTextExtentPoint\n");
1057 ret
= dc
->funcs
->pGetTextExtentPoint( dc
->physDev
, (LPCWSTR
)indices
, count
, size
);
1060 GDI_ReleaseObj( hdc
);
1062 TRACE("(%p %p %d %p): returning %ld x %ld\n",
1063 hdc
, indices
, count
, size
, size
->cx
, size
->cy
);
1068 /***********************************************************************
1069 * GetTextExtentPointA (GDI32.@)
1071 BOOL WINAPI
GetTextExtentPointA( HDC hdc
, LPCSTR str
, INT count
,
1074 TRACE("not bug compatible.\n");
1075 return GetTextExtentPoint32A( hdc
, str
, count
, size
);
1078 /***********************************************************************
1079 * GetTextExtentPointW (GDI32.@)
1081 BOOL WINAPI
GetTextExtentPointW( HDC hdc
, LPCWSTR str
, INT count
,
1084 TRACE("not bug compatible.\n");
1085 return GetTextExtentPoint32W( hdc
, str
, count
, size
);
1089 /***********************************************************************
1090 * GetTextExtentExPointA (GDI32.@)
1092 BOOL WINAPI
GetTextExtentExPointA( HDC hdc
, LPCSTR str
, INT count
,
1093 INT maxExt
, LPINT lpnFit
,
1094 LPINT alpDx
, LPSIZE size
)
1098 LPWSTR p
= FONT_mbtowc( hdc
, str
, count
, &wlen
, NULL
);
1099 ret
= GetTextExtentExPointW( hdc
, p
, wlen
, maxExt
, lpnFit
, alpDx
, size
);
1100 if (lpnFit
) *lpnFit
= WideCharToMultiByte(CP_ACP
,0,p
,*lpnFit
,NULL
,0,NULL
,NULL
);
1101 HeapFree( GetProcessHeap(), 0, p
);
1106 /***********************************************************************
1107 * GetTextExtentExPointW (GDI32.@)
1109 * Return the size of the string as it would be if it was output properly by
1112 * This should include
1113 * - Intercharacter spacing
1114 * - justification spacing (not yet done)
1115 * - kerning? see below
1117 * Kerning. Since kerning would be carried out by the rendering code it should
1118 * be done by the driver. However they don't support it yet. Also I am not
1119 * yet persuaded that (certainly under Win95) any kerning is actually done.
1121 * str: According to MSDN this should be null-terminated. That is not true; a
1122 * null will not terminate it early.
1123 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1124 * than count. I have seen it be either the size of the full string or
1125 * 1 less than the size of the full string. I have not seen it bear any
1126 * resemblance to the portion that would fit.
1127 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1128 * trailing intercharacter spacing and any trailing justification.
1131 * Currently we do this by measuring each character etc. We should do it by
1132 * passing the request to the driver, perhaps by extending the
1133 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1134 * thinking about kerning issues and rounding issues in the justification.
1137 BOOL WINAPI
GetTextExtentExPointW( HDC hdc
, LPCWSTR str
, INT count
,
1138 INT maxExt
, LPINT lpnFit
,
1139 LPINT alpDx
, LPSIZE size
)
1141 int index
, nFit
, extent
;
1145 TRACE("(%p, %s, %d)\n",hdc
,debugstr_wn(str
,count
),maxExt
);
1147 size
->cx
= size
->cy
= nFit
= extent
= 0;
1148 for(index
= 0; index
< count
; index
++)
1150 if(!GetTextExtentPoint32W( hdc
, str
, 1, &tSize
)) goto done
;
1151 /* GetTextExtentPoint includes intercharacter spacing. */
1152 /* FIXME - justification needs doing yet. Remember that the base
1153 * data will not be in logical coordinates.
1156 if( !lpnFit
|| extent
<= maxExt
)
1157 /* It is allowed to be equal. */
1160 if( alpDx
) alpDx
[index
] = extent
;
1162 if( tSize
.cy
> size
->cy
) size
->cy
= tSize
.cy
;
1166 if(lpnFit
) *lpnFit
= nFit
;
1169 TRACE("returning %d %ld x %ld\n",nFit
,size
->cx
,size
->cy
);
1175 /***********************************************************************
1176 * GetTextMetricsA (GDI32.@)
1178 BOOL WINAPI
GetTextMetricsA( HDC hdc
, TEXTMETRICA
*metrics
)
1182 if (!GetTextMetricsW( hdc
, &tm32
)) return FALSE
;
1183 FONT_TextMetricWToA( &tm32
, metrics
);
1187 /***********************************************************************
1188 * GetTextMetricsW (GDI32.@)
1190 BOOL WINAPI
GetTextMetricsW( HDC hdc
, TEXTMETRICW
*metrics
)
1193 DC
* dc
= DC_GetDCPtr( hdc
);
1194 if (!dc
) return FALSE
;
1197 ret
= WineEngGetTextMetrics(dc
->gdiFont
, metrics
);
1198 else if (dc
->funcs
->pGetTextMetrics
)
1199 ret
= dc
->funcs
->pGetTextMetrics( dc
->physDev
, metrics
);
1203 /* device layer returns values in device units
1204 * therefore we have to convert them to logical */
1206 #define WDPTOLP(x) ((x<0)? \
1207 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1208 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1209 #define HDPTOLP(y) ((y<0)? \
1210 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1211 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1213 metrics
->tmHeight
= HDPTOLP(metrics
->tmHeight
);
1214 metrics
->tmAscent
= HDPTOLP(metrics
->tmAscent
);
1215 metrics
->tmDescent
= HDPTOLP(metrics
->tmDescent
);
1216 metrics
->tmInternalLeading
= HDPTOLP(metrics
->tmInternalLeading
);
1217 metrics
->tmExternalLeading
= HDPTOLP(metrics
->tmExternalLeading
);
1218 metrics
->tmAveCharWidth
= WDPTOLP(metrics
->tmAveCharWidth
);
1219 metrics
->tmMaxCharWidth
= WDPTOLP(metrics
->tmMaxCharWidth
);
1220 metrics
->tmOverhang
= WDPTOLP(metrics
->tmOverhang
);
1224 TRACE("text metrics:\n"
1225 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1226 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1227 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1228 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1229 " PitchAndFamily = %02x\n"
1230 " --------------------\n"
1231 " InternalLeading = %li\n"
1235 metrics
->tmWeight
, metrics
->tmFirstChar
, metrics
->tmAveCharWidth
,
1236 metrics
->tmItalic
, metrics
->tmLastChar
, metrics
->tmMaxCharWidth
,
1237 metrics
->tmUnderlined
, metrics
->tmDefaultChar
, metrics
->tmOverhang
,
1238 metrics
->tmStruckOut
, metrics
->tmBreakChar
, metrics
->tmCharSet
,
1239 metrics
->tmPitchAndFamily
,
1240 metrics
->tmInternalLeading
,
1243 metrics
->tmHeight
);
1245 GDI_ReleaseObj( hdc
);
1250 /***********************************************************************
1251 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1254 * lpOTM should be LPOUTLINETEXTMETRIC
1257 * Success: Non-zero or size of required buffer
1260 UINT16 WINAPI
GetOutlineTextMetrics16(
1261 HDC16 hdc
, /* [in] Handle of device context */
1262 UINT16 cbData
, /* [in] Size of metric data array */
1263 LPOUTLINETEXTMETRIC16 lpOTM
) /* [out] Address of metric data array */
1265 FIXME("(%04x,%04x,%p): stub\n", hdc
,cbData
,lpOTM
);
1270 /***********************************************************************
1271 * GetOutlineTextMetricsA (GDI32.@)
1272 * Gets metrics for TrueType fonts.
1275 * If the supplied buffer isn't big enough Windows partially fills it up to
1276 * its given length and returns that length.
1279 * Success: Non-zero or size of required buffer
1282 UINT WINAPI
GetOutlineTextMetricsA(
1283 HDC hdc
, /* [in] Handle of device context */
1284 UINT cbData
, /* [in] Size of metric data array */
1285 LPOUTLINETEXTMETRICA lpOTM
) /* [out] Address of metric data array */
1287 char buf
[512], *ptr
;
1289 OUTLINETEXTMETRICW
*lpOTMW
= (OUTLINETEXTMETRICW
*)buf
;
1290 OUTLINETEXTMETRICA
*output
= lpOTM
;
1293 if((ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
)) == 0)
1295 if(ret
> sizeof(buf
))
1296 lpOTMW
= HeapAlloc(GetProcessHeap(), 0, ret
);
1297 GetOutlineTextMetricsW(hdc
, ret
, lpOTMW
);
1299 needed
= sizeof(OUTLINETEXTMETRICA
);
1300 if(lpOTMW
->otmpFamilyName
)
1301 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1302 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFamilyName
), -1,
1303 NULL
, 0, NULL
, NULL
);
1304 if(lpOTMW
->otmpFaceName
)
1305 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1306 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFaceName
), -1,
1307 NULL
, 0, NULL
, NULL
);
1308 if(lpOTMW
->otmpStyleName
)
1309 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1310 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpStyleName
), -1,
1311 NULL
, 0, NULL
, NULL
);
1312 if(lpOTMW
->otmpFullName
)
1313 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1314 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFullName
), -1,
1315 NULL
, 0, NULL
, NULL
);
1322 TRACE("needed = %d\n", needed
);
1324 /* Since the supplied buffer isn't big enough, we'll alloc one
1325 that is and memcpy the first cbData bytes into the lpOTM at
1327 output
= HeapAlloc(GetProcessHeap(), 0, needed
);
1329 ret
= output
->otmSize
= min(needed
, cbData
);
1330 FONT_TextMetricWToA( &lpOTMW
->otmTextMetrics
, &output
->otmTextMetrics
);
1331 output
->otmFiller
= 0;
1332 output
->otmPanoseNumber
= lpOTMW
->otmPanoseNumber
;
1333 output
->otmfsSelection
= lpOTMW
->otmfsSelection
;
1334 output
->otmfsType
= lpOTMW
->otmfsType
;
1335 output
->otmsCharSlopeRise
= lpOTMW
->otmsCharSlopeRise
;
1336 output
->otmsCharSlopeRun
= lpOTMW
->otmsCharSlopeRun
;
1337 output
->otmItalicAngle
= lpOTMW
->otmItalicAngle
;
1338 output
->otmEMSquare
= lpOTMW
->otmEMSquare
;
1339 output
->otmAscent
= lpOTMW
->otmAscent
;
1340 output
->otmDescent
= lpOTMW
->otmDescent
;
1341 output
->otmLineGap
= lpOTMW
->otmLineGap
;
1342 output
->otmsCapEmHeight
= lpOTMW
->otmsCapEmHeight
;
1343 output
->otmsXHeight
= lpOTMW
->otmsXHeight
;
1344 output
->otmrcFontBox
= lpOTMW
->otmrcFontBox
;
1345 output
->otmMacAscent
= lpOTMW
->otmMacAscent
;
1346 output
->otmMacDescent
= lpOTMW
->otmMacDescent
;
1347 output
->otmMacLineGap
= lpOTMW
->otmMacLineGap
;
1348 output
->otmusMinimumPPEM
= lpOTMW
->otmusMinimumPPEM
;
1349 output
->otmptSubscriptSize
= lpOTMW
->otmptSubscriptSize
;
1350 output
->otmptSubscriptOffset
= lpOTMW
->otmptSubscriptOffset
;
1351 output
->otmptSuperscriptSize
= lpOTMW
->otmptSuperscriptSize
;
1352 output
->otmptSuperscriptOffset
= lpOTMW
->otmptSuperscriptOffset
;
1353 output
->otmsStrikeoutSize
= lpOTMW
->otmsStrikeoutSize
;
1354 output
->otmsStrikeoutPosition
= lpOTMW
->otmsStrikeoutPosition
;
1355 output
->otmsUnderscoreSize
= lpOTMW
->otmsUnderscoreSize
;
1356 output
->otmsUnderscorePosition
= lpOTMW
->otmsUnderscorePosition
;
1359 ptr
= (char*)(output
+ 1);
1360 left
= needed
- sizeof(*output
);
1362 if(lpOTMW
->otmpFamilyName
) {
1363 output
->otmpFamilyName
= (LPSTR
)(ptr
- (char*)output
);
1364 len
= WideCharToMultiByte(CP_ACP
, 0,
1365 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFamilyName
), -1,
1366 ptr
, left
, NULL
, NULL
);
1370 output
->otmpFamilyName
= 0;
1372 if(lpOTMW
->otmpFaceName
) {
1373 output
->otmpFaceName
= (LPSTR
)(ptr
- (char*)output
);
1374 len
= WideCharToMultiByte(CP_ACP
, 0,
1375 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFaceName
), -1,
1376 ptr
, left
, NULL
, NULL
);
1380 output
->otmpFaceName
= 0;
1382 if(lpOTMW
->otmpStyleName
) {
1383 output
->otmpStyleName
= (LPSTR
)(ptr
- (char*)output
);
1384 len
= WideCharToMultiByte(CP_ACP
, 0,
1385 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpStyleName
), -1,
1386 ptr
, left
, NULL
, NULL
);
1390 output
->otmpStyleName
= 0;
1392 if(lpOTMW
->otmpFullName
) {
1393 output
->otmpFullName
= (LPSTR
)(ptr
- (char*)output
);
1394 len
= WideCharToMultiByte(CP_ACP
, 0,
1395 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFullName
), -1,
1396 ptr
, left
, NULL
, NULL
);
1399 output
->otmpFullName
= 0;
1403 if(output
!= lpOTM
) {
1404 memcpy(lpOTM
, output
, cbData
);
1405 HeapFree(GetProcessHeap(), 0, output
);
1409 if(lpOTMW
!= (OUTLINETEXTMETRICW
*)buf
)
1410 HeapFree(GetProcessHeap(), 0, lpOTMW
);
1416 /***********************************************************************
1417 * GetOutlineTextMetricsW [GDI32.@]
1419 UINT WINAPI
GetOutlineTextMetricsW(
1420 HDC hdc
, /* [in] Handle of device context */
1421 UINT cbData
, /* [in] Size of metric data array */
1422 LPOUTLINETEXTMETRICW lpOTM
) /* [out] Address of metric data array */
1424 DC
*dc
= DC_GetDCPtr( hdc
);
1425 OUTLINETEXTMETRICW
*output
= lpOTM
;
1428 TRACE("(%p,%d,%p)\n", hdc
, cbData
, lpOTM
);
1432 ret
= WineEngGetOutlineTextMetrics(dc
->gdiFont
, cbData
, output
);
1435 output
= HeapAlloc(GetProcessHeap(), 0, ret
);
1436 WineEngGetOutlineTextMetrics(dc
->gdiFont
, ret
, output
);
1439 #define WDPTOLP(x) ((x<0)? \
1440 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1441 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1442 #define HDPTOLP(y) ((y<0)? \
1443 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1444 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1446 output
->otmTextMetrics
.tmHeight
= HDPTOLP(output
->otmTextMetrics
.tmHeight
);
1447 output
->otmTextMetrics
.tmAscent
= HDPTOLP(output
->otmTextMetrics
.tmAscent
);
1448 output
->otmTextMetrics
.tmDescent
= HDPTOLP(output
->otmTextMetrics
.tmDescent
);
1449 output
->otmTextMetrics
.tmInternalLeading
= HDPTOLP(output
->otmTextMetrics
.tmInternalLeading
);
1450 output
->otmTextMetrics
.tmExternalLeading
= HDPTOLP(output
->otmTextMetrics
.tmExternalLeading
);
1451 output
->otmTextMetrics
.tmAveCharWidth
= WDPTOLP(output
->otmTextMetrics
.tmAveCharWidth
);
1452 output
->otmTextMetrics
.tmMaxCharWidth
= WDPTOLP(output
->otmTextMetrics
.tmMaxCharWidth
);
1453 output
->otmTextMetrics
.tmOverhang
= WDPTOLP(output
->otmTextMetrics
.tmOverhang
);
1454 output
->otmAscent
= HDPTOLP(output
->otmAscent
);
1455 output
->otmDescent
= HDPTOLP(output
->otmDescent
);
1456 output
->otmLineGap
= HDPTOLP(output
->otmLineGap
);
1457 output
->otmsCapEmHeight
= HDPTOLP(output
->otmsCapEmHeight
);
1458 output
->otmsXHeight
= HDPTOLP(output
->otmsXHeight
);
1459 output
->otmrcFontBox
.top
= HDPTOLP(output
->otmrcFontBox
.top
);
1460 output
->otmrcFontBox
.bottom
= HDPTOLP(output
->otmrcFontBox
.bottom
);
1461 output
->otmrcFontBox
.left
= WDPTOLP(output
->otmrcFontBox
.left
);
1462 output
->otmrcFontBox
.right
= WDPTOLP(output
->otmrcFontBox
.right
);
1463 output
->otmMacAscent
= HDPTOLP(output
->otmMacAscent
);
1464 output
->otmMacDescent
= HDPTOLP(output
->otmMacDescent
);
1465 output
->otmMacLineGap
= HDPTOLP(output
->otmMacLineGap
);
1466 output
->otmptSubscriptSize
.x
= WDPTOLP(output
->otmptSubscriptSize
.x
);
1467 output
->otmptSubscriptSize
.y
= HDPTOLP(output
->otmptSubscriptSize
.y
);
1468 output
->otmptSubscriptOffset
.x
= WDPTOLP(output
->otmptSubscriptOffset
.x
);
1469 output
->otmptSubscriptOffset
.y
= HDPTOLP(output
->otmptSubscriptOffset
.y
);
1470 output
->otmptSuperscriptSize
.x
= WDPTOLP(output
->otmptSuperscriptSize
.x
);
1471 output
->otmptSuperscriptSize
.y
= HDPTOLP(output
->otmptSuperscriptSize
.y
);
1472 output
->otmptSuperscriptOffset
.x
= WDPTOLP(output
->otmptSuperscriptOffset
.x
);
1473 output
->otmptSuperscriptOffset
.y
= HDPTOLP(output
->otmptSuperscriptOffset
.y
);
1474 output
->otmsStrikeoutSize
= HDPTOLP(output
->otmsStrikeoutSize
);
1475 output
->otmsStrikeoutPosition
= HDPTOLP(output
->otmsStrikeoutPosition
);
1476 output
->otmsUnderscoreSize
= HDPTOLP(output
->otmsUnderscoreSize
);
1477 output
->otmsUnderscorePosition
= HDPTOLP(output
->otmsUnderscorePosition
);
1480 if(output
!= lpOTM
) {
1481 memcpy(lpOTM
, output
, cbData
);
1482 HeapFree(GetProcessHeap(), 0, output
);
1488 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1489 but really this should just be a return 0. */
1491 ret
= sizeof(*lpOTM
);
1496 memset(lpOTM
, 0, ret
);
1497 lpOTM
->otmSize
= sizeof(*lpOTM
);
1498 GetTextMetricsW(hdc
, &lpOTM
->otmTextMetrics
);
1500 Further fill of the structure not implemented,
1501 Needs real values for the structure members
1506 GDI_ReleaseObj(hdc
);
1511 /***********************************************************************
1512 * GetCharWidthW (GDI32.@)
1513 * GetCharWidth32W (GDI32.@)
1515 BOOL WINAPI
GetCharWidth32W( HDC hdc
, UINT firstChar
, UINT lastChar
,
1520 DC
* dc
= DC_GetDCPtr( hdc
);
1521 if (!dc
) return FALSE
;
1524 ret
= WineEngGetCharWidth( dc
->gdiFont
, firstChar
, lastChar
, buffer
);
1525 else if (dc
->funcs
->pGetCharWidth
)
1526 ret
= dc
->funcs
->pGetCharWidth( dc
->physDev
, firstChar
, lastChar
, buffer
);
1530 /* convert device units to logical */
1531 for( i
= firstChar
; i
<= lastChar
; i
++, buffer
++ )
1532 *buffer
= INTERNAL_XDSTOWS(dc
, *buffer
);
1535 GDI_ReleaseObj( hdc
);
1540 /***********************************************************************
1541 * GetCharWidthA (GDI32.@)
1542 * GetCharWidth32A (GDI32.@)
1544 BOOL WINAPI
GetCharWidth32A( HDC hdc
, UINT firstChar
, UINT lastChar
,
1547 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
1552 if(count
<= 0) return FALSE
;
1554 str
= HeapAlloc(GetProcessHeap(), 0, count
);
1555 for(i
= 0; i
< count
; i
++)
1556 str
[i
] = (BYTE
)(firstChar
+ i
);
1558 wstr
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
1560 for(i
= 0; i
< wlen
; i
++)
1562 if(!GetCharWidth32W(hdc
, wstr
[i
], wstr
[i
], buffer
))
1570 HeapFree(GetProcessHeap(), 0, str
);
1571 HeapFree(GetProcessHeap(), 0, wstr
);
1577 /* FIXME: all following APIs ******************************************/
1580 /***********************************************************************
1581 * SetMapperFlags (GDI32.@)
1583 DWORD WINAPI
SetMapperFlags( HDC hDC
, DWORD dwFlag
)
1585 DC
*dc
= DC_GetDCPtr( hDC
);
1588 if(dc
->funcs
->pSetMapperFlags
)
1589 ret
= dc
->funcs
->pSetMapperFlags( dc
->physDev
, dwFlag
);
1591 FIXME("(%p, 0x%08lx): stub - harmless\n", hDC
, dwFlag
);
1592 GDI_ReleaseObj( hDC
);
1596 /***********************************************************************
1597 * GetAspectRatioFilterEx (GDI.486)
1599 BOOL16 WINAPI
GetAspectRatioFilterEx16( HDC16 hdc
, LPSIZE16 pAspectRatio
)
1601 FIXME("(%04x, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
1605 /***********************************************************************
1606 * GetAspectRatioFilterEx (GDI32.@)
1608 BOOL WINAPI
GetAspectRatioFilterEx( HDC hdc
, LPSIZE pAspectRatio
)
1610 FIXME("(%p, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
1615 /***********************************************************************
1616 * GetCharABCWidthsA (GDI32.@)
1618 BOOL WINAPI
GetCharABCWidthsA(HDC hdc
, UINT firstChar
, UINT lastChar
,
1621 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
1626 if(count
<= 0) return FALSE
;
1628 str
= HeapAlloc(GetProcessHeap(), 0, count
);
1629 for(i
= 0; i
< count
; i
++)
1630 str
[i
] = (BYTE
)(firstChar
+ i
);
1632 wstr
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
1634 for(i
= 0; i
< wlen
; i
++)
1636 if(!GetCharABCWidthsW(hdc
, wstr
[i
], wstr
[i
], abc
))
1644 HeapFree(GetProcessHeap(), 0, str
);
1645 HeapFree(GetProcessHeap(), 0, wstr
);
1651 /******************************************************************************
1652 * GetCharABCWidthsW [GDI32.@]
1654 * Retrieves widths of characters in range.
1657 * hdc [I] Handle of device context
1658 * firstChar [I] First character in range to query
1659 * lastChar [I] Last character in range to query
1660 * abc [O] Address of character-width structure
1663 * Only works with TrueType fonts
1669 BOOL WINAPI
GetCharABCWidthsW( HDC hdc
, UINT firstChar
, UINT lastChar
,
1672 DC
*dc
= DC_GetDCPtr(hdc
);
1677 ret
= WineEngGetCharABCWidths( dc
->gdiFont
, firstChar
, lastChar
, abc
);
1683 /* convert device units to logical */
1684 for( i
= firstChar
; i
<= lastChar
; i
++, abc
++ ) {
1685 abc
->abcA
= INTERNAL_XDSTOWS(dc
, abc
->abcA
);
1686 abc
->abcB
= INTERNAL_XDSTOWS(dc
, abc
->abcB
);
1687 abc
->abcC
= INTERNAL_XDSTOWS(dc
, abc
->abcC
);
1692 GDI_ReleaseObj(hdc
);
1697 /***********************************************************************
1698 * GetGlyphOutline (GDI.309)
1700 DWORD WINAPI
GetGlyphOutline16( HDC16 hdc
, UINT16 uChar
, UINT16 fuFormat
,
1701 LPGLYPHMETRICS16 lpgm
, DWORD cbBuffer
,
1702 LPVOID lpBuffer
, const MAT2
*lpmat2
)
1704 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1705 hdc
, uChar
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
, lpmat2
);
1706 return ~0UL; /* failure */
1710 /***********************************************************************
1711 * GetGlyphOutlineA (GDI32.@)
1713 DWORD WINAPI
GetGlyphOutlineA( HDC hdc
, UINT uChar
, UINT fuFormat
,
1714 LPGLYPHMETRICS lpgm
, DWORD cbBuffer
,
1715 LPVOID lpBuffer
, const MAT2
*lpmat2
)
1721 if(!(fuFormat
& GGO_GLYPH_INDEX
)) {
1722 p
= FONT_mbtowc(hdc
, (char*)&uChar
, 1, NULL
, NULL
);
1726 ret
= GetGlyphOutlineW(hdc
, c
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
,
1729 HeapFree(GetProcessHeap(), 0, p
);
1733 /***********************************************************************
1734 * GetGlyphOutlineW (GDI32.@)
1736 DWORD WINAPI
GetGlyphOutlineW( HDC hdc
, UINT uChar
, UINT fuFormat
,
1737 LPGLYPHMETRICS lpgm
, DWORD cbBuffer
,
1738 LPVOID lpBuffer
, const MAT2
*lpmat2
)
1740 DC
*dc
= DC_GetDCPtr(hdc
);
1743 TRACE("(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1744 hdc
, uChar
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
, lpmat2
);
1746 if(!dc
) return GDI_ERROR
;
1749 ret
= WineEngGetGlyphOutline(dc
->gdiFont
, uChar
, fuFormat
, lpgm
,
1750 cbBuffer
, lpBuffer
, lpmat2
);
1754 GDI_ReleaseObj(hdc
);
1759 /***********************************************************************
1760 * CreateScalableFontResourceA (GDI32.@)
1762 BOOL WINAPI
CreateScalableFontResourceA( DWORD fHidden
,
1763 LPCSTR lpszResourceFile
,
1764 LPCSTR lpszFontFile
,
1765 LPCSTR lpszCurrentPath
)
1769 /* fHidden=1 - only visible for the calling app, read-only, not
1770 * enumbered with EnumFonts/EnumFontFamilies
1771 * lpszCurrentPath can be NULL
1773 FIXME("(%ld,%s,%s,%s): stub\n",
1774 fHidden
, debugstr_a(lpszResourceFile
), debugstr_a(lpszFontFile
),
1775 debugstr_a(lpszCurrentPath
) );
1777 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1778 if ((f
= CreateFileA(lpszResourceFile
, 0, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0)) != INVALID_HANDLE_VALUE
) {
1780 SetLastError(ERROR_FILE_EXISTS
);
1783 return FALSE
; /* create failed */
1786 /***********************************************************************
1787 * CreateScalableFontResourceW (GDI32.@)
1789 BOOL WINAPI
CreateScalableFontResourceW( DWORD fHidden
,
1790 LPCWSTR lpszResourceFile
,
1791 LPCWSTR lpszFontFile
,
1792 LPCWSTR lpszCurrentPath
)
1794 FIXME("(%ld,%p,%p,%p): stub\n",
1795 fHidden
, lpszResourceFile
, lpszFontFile
, lpszCurrentPath
);
1796 return FALSE
; /* create failed */
1800 /*************************************************************************
1801 * GetRasterizerCaps (GDI32.@)
1803 BOOL WINAPI
GetRasterizerCaps( LPRASTERIZER_STATUS lprs
, UINT cbNumBytes
)
1805 lprs
->nSize
= sizeof(RASTERIZER_STATUS
);
1806 lprs
->wFlags
= TT_AVAILABLE
|TT_ENABLED
;
1807 lprs
->nLanguageID
= 0;
1812 /*************************************************************************
1813 * GetKerningPairsA (GDI32.@)
1815 DWORD WINAPI
GetKerningPairsA( HDC hDC
, DWORD cPairs
,
1816 LPKERNINGPAIR lpKerningPairs
)
1818 return GetKerningPairsW( hDC
, cPairs
, lpKerningPairs
);
1822 /*************************************************************************
1823 * GetKerningPairsW (GDI32.@)
1825 DWORD WINAPI
GetKerningPairsW( HDC hDC
, DWORD cPairs
,
1826 LPKERNINGPAIR lpKerningPairs
)
1829 FIXME("(%p,%ld,%p): almost empty stub!\n", hDC
, cPairs
, lpKerningPairs
);
1830 for (i
= 0; i
< cPairs
; i
++)
1831 lpKerningPairs
[i
].iKernAmount
= 0;
1835 /*************************************************************************
1836 * TranslateCharsetInfo [GDI32.@]
1838 * Fills a CHARSETINFO structure for a character set, code page, or
1839 * font. This allows making the correspondance between different labelings
1840 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1841 * of the same encoding.
1843 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1844 * only one codepage should be set in *lpSrc.
1847 * TRUE on success, FALSE on failure.
1850 BOOL WINAPI
TranslateCharsetInfo(
1851 LPDWORD lpSrc
, /* [in]
1852 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1853 if flags == TCI_SRCCHARSET: a character set value
1854 if flags == TCI_SRCCODEPAGE: a code page value
1856 LPCHARSETINFO lpCs
, /* [out] structure to receive charset information */
1857 DWORD flags
/* [in] determines interpretation of lpSrc */)
1861 case TCI_SRCFONTSIG
:
1862 while (!(*lpSrc
>>index
& 0x0001) && index
<MAXTCIINDEX
) index
++;
1864 case TCI_SRCCODEPAGE
:
1865 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciACP
&& index
< MAXTCIINDEX
) index
++;
1867 case TCI_SRCCHARSET
:
1868 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciCharset
&& index
< MAXTCIINDEX
) index
++;
1873 if (index
>= MAXTCIINDEX
|| FONT_tci
[index
].ciCharset
== DEFAULT_CHARSET
) return FALSE
;
1874 memcpy(lpCs
, &FONT_tci
[index
], sizeof(CHARSETINFO
));
1878 /*************************************************************************
1879 * GetFontLanguageInfo (GDI32.@)
1881 DWORD WINAPI
GetFontLanguageInfo(HDC hdc
)
1883 FONTSIGNATURE fontsig
;
1884 static const DWORD GCP_DBCS_MASK
=0x003F0000,
1885 GCP_DIACRITIC_MASK
=0x00000000,
1886 FLI_GLYPHS_MASK
=0x00000000,
1887 GCP_GLYPHSHAPE_MASK
=0x00000040,
1888 GCP_KASHIDA_MASK
=0x00000000,
1889 GCP_LIGATE_MASK
=0x00000000,
1890 GCP_USEKERNING_MASK
=0x00000000,
1891 GCP_REORDER_MASK
=0x00000060;
1895 GetTextCharsetInfo( hdc
, &fontsig
, 0 );
1896 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1898 if( (fontsig
.fsCsb
[0]&GCP_DBCS_MASK
)!=0 )
1901 if( (fontsig
.fsCsb
[0]&GCP_DIACRITIC_MASK
)!=0 )
1902 result
|=GCP_DIACRITIC
;
1904 if( (fontsig
.fsCsb
[0]&FLI_GLYPHS_MASK
)!=0 )
1907 if( (fontsig
.fsCsb
[0]&GCP_GLYPHSHAPE_MASK
)!=0 )
1908 result
|=GCP_GLYPHSHAPE
;
1910 if( (fontsig
.fsCsb
[0]&GCP_KASHIDA_MASK
)!=0 )
1911 result
|=GCP_KASHIDA
;
1913 if( (fontsig
.fsCsb
[0]&GCP_LIGATE_MASK
)!=0 )
1916 if( (fontsig
.fsCsb
[0]&GCP_USEKERNING_MASK
)!=0 )
1917 result
|=GCP_USEKERNING
;
1919 /* this might need a test for a HEBREW- or ARABIC_CHARSET as well */
1920 if( GetTextAlign( hdc
) & TA_RTLREADING
)
1921 if( (fontsig
.fsCsb
[0]&GCP_REORDER_MASK
)!=0 )
1922 result
|=GCP_REORDER
;
1928 /*************************************************************************
1929 * GetFontData [GDI32.@]
1931 * Retrieve data for TrueType font.
1935 * success: Number of bytes returned
1936 * failure: GDI_ERROR
1940 * Calls SetLastError()
1943 DWORD WINAPI
GetFontData(HDC hdc
, DWORD table
, DWORD offset
,
1944 LPVOID buffer
, DWORD length
)
1946 DC
*dc
= DC_GetDCPtr(hdc
);
1947 DWORD ret
= GDI_ERROR
;
1949 if(!dc
) return GDI_ERROR
;
1952 ret
= WineEngGetFontData(dc
->gdiFont
, table
, offset
, buffer
, length
);
1954 GDI_ReleaseObj(hdc
);
1958 /*************************************************************************
1959 * GetGlyphIndicesA [GDI32.@]
1961 DWORD WINAPI
GetGlyphIndicesA(HDC hdc
, LPCSTR lpstr
, INT count
,
1962 LPWORD pgi
, DWORD flags
)
1968 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1969 hdc
, debugstr_an(lpstr
, count
), count
, pgi
, flags
);
1971 lpstrW
= FONT_mbtowc(hdc
, lpstr
, count
, &countW
, NULL
);
1972 ret
= GetGlyphIndicesW(hdc
, lpstrW
, countW
, pgi
, flags
);
1973 HeapFree(GetProcessHeap(), 0, lpstrW
);
1978 /*************************************************************************
1979 * GetGlyphIndicesW [GDI32.@]
1981 DWORD WINAPI
GetGlyphIndicesW(HDC hdc
, LPCWSTR lpstr
, INT count
,
1982 LPWORD pgi
, DWORD flags
)
1984 DC
*dc
= DC_GetDCPtr(hdc
);
1985 DWORD ret
= GDI_ERROR
;
1987 TRACE("(%p, %s, %d, %p, 0x%lx)\n",
1988 hdc
, debugstr_wn(lpstr
, count
), count
, pgi
, flags
);
1990 if(!dc
) return GDI_ERROR
;
1993 ret
= WineEngGetGlyphIndices(dc
->gdiFont
, lpstr
, count
, pgi
, flags
);
1995 GDI_ReleaseObj(hdc
);
1999 /*************************************************************************
2000 * GetCharacterPlacementA [GDI32.@]
2003 * the web browser control of ie4 calls this with dwFlags=0
2006 GetCharacterPlacementA(HDC hdc
, LPCSTR lpString
, INT uCount
,
2007 INT nMaxExtent
, GCP_RESULTSA
*lpResults
,
2012 GCP_RESULTSW resultsW
;
2016 TRACE("%s, %d, %d, 0x%08lx\n",
2017 debugstr_an(lpString
, uCount
), uCount
, nMaxExtent
, dwFlags
);
2019 /* both structs are equal in size */
2020 memcpy(&resultsW
, lpResults
, sizeof(resultsW
));
2022 lpStringW
= FONT_mbtowc(hdc
, lpString
, uCount
, &uCountW
, &font_cp
);
2023 if(lpResults
->lpOutString
)
2024 resultsW
.lpOutString
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*uCountW
);
2026 ret
= GetCharacterPlacementW(hdc
, lpStringW
, uCountW
, nMaxExtent
, &resultsW
, dwFlags
);
2028 if(lpResults
->lpOutString
) {
2029 WideCharToMultiByte(font_cp
, 0, resultsW
.lpOutString
, uCountW
,
2030 lpResults
->lpOutString
, uCount
, NULL
, NULL
);
2033 HeapFree(GetProcessHeap(), 0, lpStringW
);
2034 HeapFree(GetProcessHeap(), 0, resultsW
.lpOutString
);
2039 /*************************************************************************
2040 * GetCharacterPlacementW [GDI32.@]
2042 * Retrieve information about a string. This includes the width, reordering,
2043 * Glyphing and so on.
2047 * The width and height of the string if successful, 0 if failed.
2051 * All flags except GCP_REORDER are not yet implemented.
2052 * Reordering is not 100% complient to the Windows BiDi method.
2053 * Caret positioning is not yet implemented for BiDi.
2054 * Classes are not yet implemented.
2058 GetCharacterPlacementW(
2059 HDC hdc
, /* [in] Device context for which the rendering is to be done */
2060 LPCWSTR lpString
, /* [in] The string for which information is to be returned */
2061 INT uCount
, /* [in] Number of WORDS in string. */
2062 INT nMaxExtent
, /* [in] Maximum extent the string is to take (in HDC logical units) */
2063 GCP_RESULTSW
*lpResults
,/* [in/out] A pointer to a GCP_RESULTSW struct */
2064 DWORD dwFlags
/* [in] Flags specifying how to process the string */
2071 TRACE("%s, %d, %d, 0x%08lx\n",
2072 debugstr_wn(lpString
, uCount
), uCount
, nMaxExtent
, dwFlags
);
2074 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2075 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2076 lpResults
->lStructSize
, lpResults
->lpOutString
, lpResults
->lpOrder
,
2077 lpResults
->lpDx
, lpResults
->lpCaretPos
, lpResults
->lpClass
,
2078 lpResults
->lpGlyphs
, lpResults
->nGlyphs
, lpResults
->nMaxFit
);
2080 if(dwFlags
&(~GCP_REORDER
)) FIXME("flags 0x%08lx ignored\n", dwFlags
);
2081 if(lpResults
->lpClass
) FIXME("classes not implemented\n");
2082 if (lpResults
->lpCaretPos
&& (dwFlags
& GCP_REORDER
))
2083 FIXME("Caret positions for complex scripts not implemented\n");
2085 nSet
= (UINT
)uCount
;
2086 if(nSet
> lpResults
->nGlyphs
)
2087 nSet
= lpResults
->nGlyphs
;
2089 /* return number of initialized fields */
2090 lpResults
->nGlyphs
= nSet
;
2092 if((dwFlags
&GCP_REORDER
)==0 || !BidiAvail
)
2094 /* Treat the case where no special handling was requested in a fastpath way */
2095 /* copy will do if the GCP_REORDER flag is not set */
2096 if(lpResults
->lpOutString
)
2097 strncpyW( lpResults
->lpOutString
, lpString
, nSet
);
2099 if(lpResults
->lpOrder
)
2101 for(i
= 0; i
< nSet
; i
++)
2102 lpResults
->lpOrder
[i
] = i
;
2106 BIDI_Reorder( lpString
, uCount
, dwFlags
, WINE_GCPW_FORCE_LTR
, lpResults
->lpOutString
,
2107 nSet
, lpResults
->lpOrder
);
2110 /* FIXME: Will use the placement chars */
2111 if (lpResults
->lpDx
)
2114 for (i
= 0; i
< nSet
; i
++)
2116 if (GetCharWidth32W(hdc
, lpString
[i
], lpString
[i
], &c
))
2117 lpResults
->lpDx
[i
]= c
;
2121 if (lpResults
->lpCaretPos
&& !(dwFlags
& GCP_REORDER
))
2125 lpResults
->lpCaretPos
[0] = 0;
2126 for (i
= 1; i
< nSet
; i
++)
2127 if (GetTextExtentPoint32W(hdc
, &(lpString
[i
- 1]), 1, &size
))
2128 lpResults
->lpCaretPos
[i
] = (pos
+= size
.cx
);
2131 if(lpResults
->lpGlyphs
)
2132 GetGlyphIndicesW(hdc
, lpString
, nSet
, lpResults
->lpGlyphs
, 0);
2134 if (GetTextExtentPoint32W(hdc
, lpString
, uCount
, &size
))
2135 ret
= MAKELONG(size
.cx
, size
.cy
);
2140 /*************************************************************************
2141 * GetCharABCWidthsFloatA [GDI32.@]
2143 BOOL WINAPI
GetCharABCWidthsFloatA(HDC hdc
, UINT iFirstChar
, UINT iLastChar
,
2146 FIXME_(gdi
)("GetCharABCWidthsFloatA, stub\n");
2150 /*************************************************************************
2151 * GetCharABCWidthsFloatW [GDI32.@]
2153 BOOL WINAPI
GetCharABCWidthsFloatW(HDC hdc
, UINT iFirstChar
,
2154 UINT iLastChar
, LPABCFLOAT lpABCF
)
2156 FIXME_(gdi
)("GetCharABCWidthsFloatW, stub\n");
2160 /*************************************************************************
2161 * GetCharWidthFloatA [GDI32.@]
2163 BOOL WINAPI
GetCharWidthFloatA(HDC hdc
, UINT iFirstChar
,
2164 UINT iLastChar
, PFLOAT pxBuffer
)
2166 FIXME_(gdi
)("GetCharWidthFloatA, stub\n");
2170 /*************************************************************************
2171 * GetCharWidthFloatW [GDI32.@]
2173 BOOL WINAPI
GetCharWidthFloatW(HDC hdc
, UINT iFirstChar
,
2174 UINT iLastChar
, PFLOAT pxBuffer
)
2176 FIXME_(gdi
)("GetCharWidthFloatW, stub\n");
2181 /***********************************************************************
2183 * Font Resource API *
2185 ***********************************************************************/
2187 /***********************************************************************
2188 * AddFontResourceA (GDI32.@)
2190 INT WINAPI
AddFontResourceA( LPCSTR str
)
2192 return AddFontResourceExA( str
, 0, NULL
);
2195 /***********************************************************************
2196 * AddFontResourceW (GDI32.@)
2198 INT WINAPI
AddFontResourceW( LPCWSTR str
)
2200 return AddFontResourceExW(str
, 0, NULL
);
2204 /***********************************************************************
2205 * AddFontResourceExA (GDI32.@)
2207 INT WINAPI
AddFontResourceExA( LPCSTR str
, DWORD fl
, PVOID pdv
)
2209 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
2210 LPWSTR strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2213 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2214 ret
= AddFontResourceExW(strW
, fl
, pdv
);
2215 HeapFree(GetProcessHeap(), 0, strW
);
2219 /***********************************************************************
2220 * AddFontResourceExW (GDI32.@)
2222 INT WINAPI
AddFontResourceExW( LPCWSTR str
, DWORD fl
, PVOID pdv
)
2224 return WineEngAddFontResourceEx(str
, fl
, pdv
);
2227 /***********************************************************************
2228 * RemoveFontResourceA (GDI32.@)
2230 BOOL WINAPI
RemoveFontResourceA( LPCSTR str
)
2232 return RemoveFontResourceExA(str
, 0, 0);
2235 /***********************************************************************
2236 * RemoveFontResourceW (GDI32.@)
2238 BOOL WINAPI
RemoveFontResourceW( LPCWSTR str
)
2240 return RemoveFontResourceExW(str
, 0, 0);
2243 /***********************************************************************
2244 * RemoveFontResourceExA (GDI32.@)
2246 BOOL WINAPI
RemoveFontResourceExA( LPCSTR str
, DWORD fl
, PVOID pdv
)
2248 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
2249 LPWSTR strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2252 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2253 ret
= RemoveFontResourceExW(strW
, fl
, pdv
);
2254 HeapFree(GetProcessHeap(), 0, strW
);
2258 /***********************************************************************
2259 * RemoveFontResourceExW (GDI32.@)
2261 BOOL WINAPI
RemoveFontResourceExW( LPCWSTR str
, DWORD fl
, PVOID pdv
)
2263 return WineEngRemoveFontResourceEx(str
, fl
, pdv
);
2266 /***********************************************************************
2267 * GetTextCharset (GDI32.@)
2269 UINT WINAPI
GetTextCharset(HDC hdc
)
2271 /* MSDN docs say this is equivalent */
2272 return GetTextCharsetInfo(hdc
, NULL
, 0);
2275 /***********************************************************************
2276 * GetTextCharsetInfo (GDI32.@)
2278 UINT WINAPI
GetTextCharsetInfo(HDC hdc
, LPFONTSIGNATURE fs
, DWORD flags
)
2280 UINT ret
= DEFAULT_CHARSET
;
2281 DC
*dc
= DC_GetDCPtr(hdc
);
2286 ret
= WineEngGetTextCharsetInfo(dc
->gdiFont
, fs
, flags
);
2288 GDI_ReleaseObj(hdc
);
2291 if (ret
== DEFAULT_CHARSET
&& fs
)
2292 memset(fs
, 0, sizeof(FONTSIGNATURE
));