4 * Copyright 1993 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wine/unicode.h"
29 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(font
);
33 WINE_DECLARE_DEBUG_CHANNEL(gdi
);
35 static HGDIOBJ
FONT_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
);
36 static INT
FONT_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
37 static INT
FONT_GetObjectA( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
38 static INT
FONT_GetObjectW( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
39 static BOOL
FONT_DeleteObject( HGDIOBJ handle
, void *obj
);
41 static const struct gdi_obj_funcs font_funcs
=
43 FONT_SelectObject
, /* pSelectObject */
44 FONT_GetObject16
, /* pGetObject16 */
45 FONT_GetObjectA
, /* pGetObjectA */
46 FONT_GetObjectW
, /* pGetObjectW */
47 NULL
, /* pUnrealizeObject */
48 FONT_DeleteObject
/* pDeleteObject */
51 #define ENUM_UNICODE 0x00000001
52 #define ENUM_CALLED 0x00000002
62 LPLOGFONT16 lpLogFontParam
;
63 FONTENUMPROCEX16 lpEnumFunc
;
66 LPNEWTEXTMETRICEX16 lpTextMetric
;
67 LPENUMLOGFONTEX16 lpLogFont
;
77 LPLOGFONTW lpLogFontParam
;
78 FONTENUMPROCEXW lpEnumFunc
;
87 * For TranslateCharsetInfo
89 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
90 #define MAXTCIINDEX 32
91 static CHARSETINFO FONT_tci
[MAXTCIINDEX
] = {
93 { ANSI_CHARSET
, 1252, FS(0)},
94 { EASTEUROPE_CHARSET
, 1250, FS(1)},
95 { RUSSIAN_CHARSET
, 1251, FS(2)},
96 { GREEK_CHARSET
, 1253, FS(3)},
97 { TURKISH_CHARSET
, 1254, FS(4)},
98 { HEBREW_CHARSET
, 1255, FS(5)},
99 { ARABIC_CHARSET
, 1256, FS(6)},
100 { BALTIC_CHARSET
, 1257, FS(7)},
101 { VIETNAMESE_CHARSET
, 1258, FS(8)},
102 /* reserved by ANSI */
103 { DEFAULT_CHARSET
, 0, FS(0)},
104 { DEFAULT_CHARSET
, 0, FS(0)},
105 { DEFAULT_CHARSET
, 0, FS(0)},
106 { DEFAULT_CHARSET
, 0, FS(0)},
107 { DEFAULT_CHARSET
, 0, FS(0)},
108 { DEFAULT_CHARSET
, 0, FS(0)},
109 { DEFAULT_CHARSET
, 0, FS(0)},
111 { THAI_CHARSET
, 874, FS(16)},
112 { SHIFTJIS_CHARSET
, 932, FS(17)},
113 { GB2312_CHARSET
, 936, FS(18)},
114 { HANGEUL_CHARSET
, 949, FS(19)},
115 { CHINESEBIG5_CHARSET
, 950, FS(20)},
116 { JOHAB_CHARSET
, 1361, FS(21)},
117 /* reserved for alternate ANSI and OEM */
118 { DEFAULT_CHARSET
, 0, FS(0)},
119 { DEFAULT_CHARSET
, 0, FS(0)},
120 { DEFAULT_CHARSET
, 0, FS(0)},
121 { DEFAULT_CHARSET
, 0, FS(0)},
122 { DEFAULT_CHARSET
, 0, FS(0)},
123 { DEFAULT_CHARSET
, 0, FS(0)},
124 { DEFAULT_CHARSET
, 0, FS(0)},
125 { DEFAULT_CHARSET
, 0, FS(0)},
126 /* reserved for system */
127 { DEFAULT_CHARSET
, 0, FS(0)},
128 { SYMBOL_CHARSET
, CP_SYMBOL
, FS(31)},
131 /* ### start build ### */
132 extern WORD CALLBACK
FONT_CallTo16_word_llwl(FONTENUMPROCEX16
,LONG
,LONG
,WORD
,LONG
);
133 /* ### stop build ### */
135 /***********************************************************************
136 * LOGFONT conversion functions.
138 void FONT_LogFontATo16( const LOGFONTA
* font32
, LPLOGFONT16 font16
)
140 font16
->lfHeight
= font32
->lfHeight
;
141 font16
->lfWidth
= font32
->lfWidth
;
142 font16
->lfEscapement
= font32
->lfEscapement
;
143 font16
->lfOrientation
= font32
->lfOrientation
;
144 font16
->lfWeight
= font32
->lfWeight
;
145 font16
->lfItalic
= font32
->lfItalic
;
146 font16
->lfUnderline
= font32
->lfUnderline
;
147 font16
->lfStrikeOut
= font32
->lfStrikeOut
;
148 font16
->lfCharSet
= font32
->lfCharSet
;
149 font16
->lfOutPrecision
= font32
->lfOutPrecision
;
150 font16
->lfClipPrecision
= font32
->lfClipPrecision
;
151 font16
->lfQuality
= font32
->lfQuality
;
152 font16
->lfPitchAndFamily
= font32
->lfPitchAndFamily
;
153 lstrcpynA( font16
->lfFaceName
, font32
->lfFaceName
, LF_FACESIZE
);
156 void FONT_LogFontWTo16( const LOGFONTW
* font32
, LPLOGFONT16 font16
)
158 font16
->lfHeight
= font32
->lfHeight
;
159 font16
->lfWidth
= font32
->lfWidth
;
160 font16
->lfEscapement
= font32
->lfEscapement
;
161 font16
->lfOrientation
= font32
->lfOrientation
;
162 font16
->lfWeight
= font32
->lfWeight
;
163 font16
->lfItalic
= font32
->lfItalic
;
164 font16
->lfUnderline
= font32
->lfUnderline
;
165 font16
->lfStrikeOut
= font32
->lfStrikeOut
;
166 font16
->lfCharSet
= font32
->lfCharSet
;
167 font16
->lfOutPrecision
= font32
->lfOutPrecision
;
168 font16
->lfClipPrecision
= font32
->lfClipPrecision
;
169 font16
->lfQuality
= font32
->lfQuality
;
170 font16
->lfPitchAndFamily
= font32
->lfPitchAndFamily
;
171 WideCharToMultiByte( CP_ACP
, 0, font32
->lfFaceName
, -1,
172 font16
->lfFaceName
, LF_FACESIZE
, NULL
, NULL
);
173 font16
->lfFaceName
[LF_FACESIZE
-1] = 0;
176 void FONT_LogFont16ToA( const LOGFONT16
*font16
, LPLOGFONTA font32
)
178 font32
->lfHeight
= font16
->lfHeight
;
179 font32
->lfWidth
= font16
->lfWidth
;
180 font32
->lfEscapement
= font16
->lfEscapement
;
181 font32
->lfOrientation
= font16
->lfOrientation
;
182 font32
->lfWeight
= font16
->lfWeight
;
183 font32
->lfItalic
= font16
->lfItalic
;
184 font32
->lfUnderline
= font16
->lfUnderline
;
185 font32
->lfStrikeOut
= font16
->lfStrikeOut
;
186 font32
->lfCharSet
= font16
->lfCharSet
;
187 font32
->lfOutPrecision
= font16
->lfOutPrecision
;
188 font32
->lfClipPrecision
= font16
->lfClipPrecision
;
189 font32
->lfQuality
= font16
->lfQuality
;
190 font32
->lfPitchAndFamily
= font16
->lfPitchAndFamily
;
191 lstrcpynA( font32
->lfFaceName
, font16
->lfFaceName
, LF_FACESIZE
);
194 void FONT_LogFont16ToW( const LOGFONT16
*font16
, LPLOGFONTW font32
)
196 font32
->lfHeight
= font16
->lfHeight
;
197 font32
->lfWidth
= font16
->lfWidth
;
198 font32
->lfEscapement
= font16
->lfEscapement
;
199 font32
->lfOrientation
= font16
->lfOrientation
;
200 font32
->lfWeight
= font16
->lfWeight
;
201 font32
->lfItalic
= font16
->lfItalic
;
202 font32
->lfUnderline
= font16
->lfUnderline
;
203 font32
->lfStrikeOut
= font16
->lfStrikeOut
;
204 font32
->lfCharSet
= font16
->lfCharSet
;
205 font32
->lfOutPrecision
= font16
->lfOutPrecision
;
206 font32
->lfClipPrecision
= font16
->lfClipPrecision
;
207 font32
->lfQuality
= font16
->lfQuality
;
208 font32
->lfPitchAndFamily
= font16
->lfPitchAndFamily
;
209 MultiByteToWideChar( CP_ACP
, 0, font16
->lfFaceName
, -1, font32
->lfFaceName
, LF_FACESIZE
);
210 font32
->lfFaceName
[LF_FACESIZE
-1] = 0;
213 void FONT_LogFontAToW( const LOGFONTA
*fontA
, LPLOGFONTW fontW
)
215 memcpy(fontW
, fontA
, sizeof(LOGFONTA
) - LF_FACESIZE
);
216 MultiByteToWideChar(CP_ACP
, 0, fontA
->lfFaceName
, -1, fontW
->lfFaceName
,
220 void FONT_LogFontWToA( const LOGFONTW
*fontW
, LPLOGFONTA fontA
)
222 memcpy(fontA
, fontW
, sizeof(LOGFONTA
) - LF_FACESIZE
);
223 WideCharToMultiByte(CP_ACP
, 0, fontW
->lfFaceName
, -1, fontA
->lfFaceName
,
224 LF_FACESIZE
, NULL
, NULL
);
227 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16
*font16
, LPENUMLOGFONTEXA font32
)
229 FONT_LogFont16ToA( (LPLOGFONT16
)font16
, (LPLOGFONTA
)font32
);
230 lstrcpynA( font32
->elfFullName
, font16
->elfFullName
, LF_FULLFACESIZE
);
231 lstrcpynA( font32
->elfStyle
, font16
->elfStyle
, LF_FACESIZE
);
232 lstrcpynA( font32
->elfScript
, font16
->elfScript
, LF_FACESIZE
);
235 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16
*font16
, LPENUMLOGFONTEXW font32
)
237 FONT_LogFont16ToW( (LPLOGFONT16
)font16
, (LPLOGFONTW
)font32
);
239 MultiByteToWideChar( CP_ACP
, 0, font16
->elfFullName
, -1, font32
->elfFullName
, LF_FULLFACESIZE
);
240 font32
->elfFullName
[LF_FULLFACESIZE
-1] = 0;
241 MultiByteToWideChar( CP_ACP
, 0, font16
->elfStyle
, -1, font32
->elfStyle
, LF_FACESIZE
);
242 font32
->elfStyle
[LF_FACESIZE
-1] = 0;
243 MultiByteToWideChar( CP_ACP
, 0, font16
->elfScript
, -1, font32
->elfScript
, LF_FACESIZE
);
244 font32
->elfScript
[LF_FACESIZE
-1] = 0;
247 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW
*fontW
, LPENUMLOGFONTEX16 font16
)
249 FONT_LogFontWTo16( (LPLOGFONTW
)fontW
, (LPLOGFONT16
)font16
);
251 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfFullName
, -1,
252 font16
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
253 font16
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
254 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfStyle
, -1,
255 font16
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
256 font16
->elfStyle
[LF_FACESIZE
-1] = '\0';
257 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfScript
, -1,
258 font16
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
259 font16
->elfScript
[LF_FACESIZE
-1] = '\0';
262 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW
*fontW
, LPENUMLOGFONTEXA fontA
)
264 FONT_LogFontWToA( (LPLOGFONTW
)fontW
, (LPLOGFONTA
)fontA
);
266 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfFullName
, -1,
267 fontA
->elfFullName
, LF_FULLFACESIZE
, NULL
, NULL
);
268 fontA
->elfFullName
[LF_FULLFACESIZE
-1] = '\0';
269 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfStyle
, -1,
270 fontA
->elfStyle
, LF_FACESIZE
, NULL
, NULL
);
271 fontA
->elfStyle
[LF_FACESIZE
-1] = '\0';
272 WideCharToMultiByte( CP_ACP
, 0, fontW
->elfScript
, -1,
273 fontA
->elfScript
, LF_FACESIZE
, NULL
, NULL
);
274 fontA
->elfScript
[LF_FACESIZE
-1] = '\0';
277 /***********************************************************************
278 * TEXTMETRIC conversion functions.
280 void FONT_TextMetricATo16(const TEXTMETRICA
*ptm32
, LPTEXTMETRIC16 ptm16
)
282 ptm16
->tmHeight
= ptm32
->tmHeight
;
283 ptm16
->tmAscent
= ptm32
->tmAscent
;
284 ptm16
->tmDescent
= ptm32
->tmDescent
;
285 ptm16
->tmInternalLeading
= ptm32
->tmInternalLeading
;
286 ptm16
->tmExternalLeading
= ptm32
->tmExternalLeading
;
287 ptm16
->tmAveCharWidth
= ptm32
->tmAveCharWidth
;
288 ptm16
->tmMaxCharWidth
= ptm32
->tmMaxCharWidth
;
289 ptm16
->tmWeight
= ptm32
->tmWeight
;
290 ptm16
->tmOverhang
= ptm32
->tmOverhang
;
291 ptm16
->tmDigitizedAspectX
= ptm32
->tmDigitizedAspectX
;
292 ptm16
->tmDigitizedAspectY
= ptm32
->tmDigitizedAspectY
;
293 ptm16
->tmFirstChar
= ptm32
->tmFirstChar
;
294 ptm16
->tmLastChar
= ptm32
->tmLastChar
;
295 ptm16
->tmDefaultChar
= ptm32
->tmDefaultChar
;
296 ptm16
->tmBreakChar
= ptm32
->tmBreakChar
;
297 ptm16
->tmItalic
= ptm32
->tmItalic
;
298 ptm16
->tmUnderlined
= ptm32
->tmUnderlined
;
299 ptm16
->tmStruckOut
= ptm32
->tmStruckOut
;
300 ptm16
->tmPitchAndFamily
= ptm32
->tmPitchAndFamily
;
301 ptm16
->tmCharSet
= ptm32
->tmCharSet
;
304 void FONT_TextMetricWTo16(const TEXTMETRICW
*ptm32
, LPTEXTMETRIC16 ptm16
)
306 ptm16
->tmHeight
= ptm32
->tmHeight
;
307 ptm16
->tmAscent
= ptm32
->tmAscent
;
308 ptm16
->tmDescent
= ptm32
->tmDescent
;
309 ptm16
->tmInternalLeading
= ptm32
->tmInternalLeading
;
310 ptm16
->tmExternalLeading
= ptm32
->tmExternalLeading
;
311 ptm16
->tmAveCharWidth
= ptm32
->tmAveCharWidth
;
312 ptm16
->tmMaxCharWidth
= ptm32
->tmMaxCharWidth
;
313 ptm16
->tmWeight
= ptm32
->tmWeight
;
314 ptm16
->tmOverhang
= ptm32
->tmOverhang
;
315 ptm16
->tmDigitizedAspectX
= ptm32
->tmDigitizedAspectX
;
316 ptm16
->tmDigitizedAspectY
= ptm32
->tmDigitizedAspectY
;
317 ptm16
->tmFirstChar
= ptm32
->tmFirstChar
;
318 ptm16
->tmLastChar
= ptm32
->tmLastChar
;
319 ptm16
->tmDefaultChar
= ptm32
->tmDefaultChar
;
320 ptm16
->tmBreakChar
= ptm32
->tmBreakChar
;
321 ptm16
->tmItalic
= ptm32
->tmItalic
;
322 ptm16
->tmUnderlined
= ptm32
->tmUnderlined
;
323 ptm16
->tmStruckOut
= ptm32
->tmStruckOut
;
324 ptm16
->tmPitchAndFamily
= ptm32
->tmPitchAndFamily
;
325 ptm16
->tmCharSet
= ptm32
->tmCharSet
;
328 void FONT_TextMetric16ToA(const TEXTMETRIC16
*ptm16
, LPTEXTMETRICA ptm32
)
330 ptm32
->tmHeight
= ptm16
->tmHeight
;
331 ptm32
->tmAscent
= ptm16
->tmAscent
;
332 ptm32
->tmDescent
= ptm16
->tmDescent
;
333 ptm32
->tmInternalLeading
= ptm16
->tmInternalLeading
;
334 ptm32
->tmExternalLeading
= ptm16
->tmExternalLeading
;
335 ptm32
->tmAveCharWidth
= ptm16
->tmAveCharWidth
;
336 ptm32
->tmMaxCharWidth
= ptm16
->tmMaxCharWidth
;
337 ptm32
->tmWeight
= ptm16
->tmWeight
;
338 ptm32
->tmOverhang
= ptm16
->tmOverhang
;
339 ptm32
->tmDigitizedAspectX
= ptm16
->tmDigitizedAspectX
;
340 ptm32
->tmDigitizedAspectY
= ptm16
->tmDigitizedAspectY
;
341 ptm32
->tmFirstChar
= ptm16
->tmFirstChar
;
342 ptm32
->tmLastChar
= ptm16
->tmLastChar
;
343 ptm32
->tmDefaultChar
= ptm16
->tmDefaultChar
;
344 ptm32
->tmBreakChar
= ptm16
->tmBreakChar
;
345 ptm32
->tmItalic
= ptm16
->tmItalic
;
346 ptm32
->tmUnderlined
= ptm16
->tmUnderlined
;
347 ptm32
->tmStruckOut
= ptm16
->tmStruckOut
;
348 ptm32
->tmPitchAndFamily
= ptm16
->tmPitchAndFamily
;
349 ptm32
->tmCharSet
= ptm16
->tmCharSet
;
352 void FONT_TextMetric16ToW(const TEXTMETRIC16
*ptm16
, LPTEXTMETRICW ptm32
)
354 ptm32
->tmHeight
= ptm16
->tmHeight
;
355 ptm32
->tmAscent
= ptm16
->tmAscent
;
356 ptm32
->tmDescent
= ptm16
->tmDescent
;
357 ptm32
->tmInternalLeading
= ptm16
->tmInternalLeading
;
358 ptm32
->tmExternalLeading
= ptm16
->tmExternalLeading
;
359 ptm32
->tmAveCharWidth
= ptm16
->tmAveCharWidth
;
360 ptm32
->tmMaxCharWidth
= ptm16
->tmMaxCharWidth
;
361 ptm32
->tmWeight
= ptm16
->tmWeight
;
362 ptm32
->tmOverhang
= ptm16
->tmOverhang
;
363 ptm32
->tmDigitizedAspectX
= ptm16
->tmDigitizedAspectX
;
364 ptm32
->tmDigitizedAspectY
= ptm16
->tmDigitizedAspectY
;
365 ptm32
->tmFirstChar
= ptm16
->tmFirstChar
;
366 ptm32
->tmLastChar
= ptm16
->tmLastChar
;
367 ptm32
->tmDefaultChar
= ptm16
->tmDefaultChar
;
368 ptm32
->tmBreakChar
= ptm16
->tmBreakChar
;
369 ptm32
->tmItalic
= ptm16
->tmItalic
;
370 ptm32
->tmUnderlined
= ptm16
->tmUnderlined
;
371 ptm32
->tmStruckOut
= ptm16
->tmStruckOut
;
372 ptm32
->tmPitchAndFamily
= ptm16
->tmPitchAndFamily
;
373 ptm32
->tmCharSet
= ptm16
->tmCharSet
;
376 void FONT_TextMetricAToW(const TEXTMETRICA
*ptm32A
, LPTEXTMETRICW ptm32W
)
378 ptm32W
->tmHeight
= ptm32A
->tmHeight
;
379 ptm32W
->tmAscent
= ptm32A
->tmAscent
;
380 ptm32W
->tmDescent
= ptm32A
->tmDescent
;
381 ptm32W
->tmInternalLeading
= ptm32A
->tmInternalLeading
;
382 ptm32W
->tmExternalLeading
= ptm32A
->tmExternalLeading
;
383 ptm32W
->tmAveCharWidth
= ptm32A
->tmAveCharWidth
;
384 ptm32W
->tmMaxCharWidth
= ptm32A
->tmMaxCharWidth
;
385 ptm32W
->tmWeight
= ptm32A
->tmWeight
;
386 ptm32W
->tmOverhang
= ptm32A
->tmOverhang
;
387 ptm32W
->tmDigitizedAspectX
= ptm32A
->tmDigitizedAspectX
;
388 ptm32W
->tmDigitizedAspectY
= ptm32A
->tmDigitizedAspectY
;
389 ptm32W
->tmFirstChar
= ptm32A
->tmFirstChar
;
390 ptm32W
->tmLastChar
= ptm32A
->tmLastChar
;
391 ptm32W
->tmDefaultChar
= ptm32A
->tmDefaultChar
;
392 ptm32W
->tmBreakChar
= ptm32A
->tmBreakChar
;
393 ptm32W
->tmItalic
= ptm32A
->tmItalic
;
394 ptm32W
->tmUnderlined
= ptm32A
->tmUnderlined
;
395 ptm32W
->tmStruckOut
= ptm32A
->tmStruckOut
;
396 ptm32W
->tmPitchAndFamily
= ptm32A
->tmPitchAndFamily
;
397 ptm32W
->tmCharSet
= ptm32A
->tmCharSet
;
400 void FONT_TextMetricWToA(const TEXTMETRICW
*ptmW
, LPTEXTMETRICA ptmA
)
402 ptmA
->tmHeight
= ptmW
->tmHeight
;
403 ptmA
->tmAscent
= ptmW
->tmAscent
;
404 ptmA
->tmDescent
= ptmW
->tmDescent
;
405 ptmA
->tmInternalLeading
= ptmW
->tmInternalLeading
;
406 ptmA
->tmExternalLeading
= ptmW
->tmExternalLeading
;
407 ptmA
->tmAveCharWidth
= ptmW
->tmAveCharWidth
;
408 ptmA
->tmMaxCharWidth
= ptmW
->tmMaxCharWidth
;
409 ptmA
->tmWeight
= ptmW
->tmWeight
;
410 ptmA
->tmOverhang
= ptmW
->tmOverhang
;
411 ptmA
->tmDigitizedAspectX
= ptmW
->tmDigitizedAspectX
;
412 ptmA
->tmDigitizedAspectY
= ptmW
->tmDigitizedAspectY
;
413 ptmA
->tmFirstChar
= ptmW
->tmFirstChar
;
414 ptmA
->tmLastChar
= ptmW
->tmLastChar
;
415 ptmA
->tmDefaultChar
= ptmW
->tmDefaultChar
;
416 ptmA
->tmBreakChar
= ptmW
->tmBreakChar
;
417 ptmA
->tmItalic
= ptmW
->tmItalic
;
418 ptmA
->tmUnderlined
= ptmW
->tmUnderlined
;
419 ptmA
->tmStruckOut
= ptmW
->tmStruckOut
;
420 ptmA
->tmPitchAndFamily
= ptmW
->tmPitchAndFamily
;
421 ptmA
->tmCharSet
= ptmW
->tmCharSet
;
425 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW
*ptmW
, LPNEWTEXTMETRICEX16 ptm16
)
427 FONT_TextMetricWTo16((LPTEXTMETRICW
)ptmW
, (LPTEXTMETRIC16
)ptm16
);
428 ptm16
->ntmTm
.ntmFlags
= ptmW
->ntmTm
.ntmFlags
;
429 ptm16
->ntmTm
.ntmSizeEM
= ptmW
->ntmTm
.ntmSizeEM
;
430 ptm16
->ntmTm
.ntmCellHeight
= ptmW
->ntmTm
.ntmCellHeight
;
431 ptm16
->ntmTm
.ntmAvgWidth
= ptmW
->ntmTm
.ntmAvgWidth
;
432 memcpy(&ptm16
->ntmFontSig
, &ptmW
->ntmFontSig
, sizeof(FONTSIGNATURE
));
435 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW
*ptmW
, LPNEWTEXTMETRICEXA ptmA
)
437 FONT_TextMetricWToA((LPTEXTMETRICW
)ptmW
, (LPTEXTMETRICA
)ptmA
);
438 ptmA
->ntmTm
.ntmFlags
= ptmW
->ntmTm
.ntmFlags
;
439 ptmA
->ntmTm
.ntmSizeEM
= ptmW
->ntmTm
.ntmSizeEM
;
440 ptmA
->ntmTm
.ntmCellHeight
= ptmW
->ntmTm
.ntmCellHeight
;
441 ptmA
->ntmTm
.ntmAvgWidth
= ptmW
->ntmTm
.ntmAvgWidth
;
442 memcpy(&ptmA
->ntmFontSig
, &ptmW
->ntmFontSig
, sizeof(FONTSIGNATURE
));
445 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16
*ptm16
, LPNEWTEXTMETRICEXW ptmW
)
447 FONT_TextMetric16ToW((LPTEXTMETRIC16
)ptm16
, (LPTEXTMETRICW
)ptmW
);
448 ptmW
->ntmTm
.ntmFlags
= ptm16
->ntmTm
.ntmFlags
;
449 ptmW
->ntmTm
.ntmSizeEM
= ptm16
->ntmTm
.ntmSizeEM
;
450 ptmW
->ntmTm
.ntmCellHeight
= ptm16
->ntmTm
.ntmCellHeight
;
451 ptmW
->ntmTm
.ntmAvgWidth
= ptm16
->ntmTm
.ntmAvgWidth
;
452 memcpy(&ptmW
->ntmFontSig
, &ptm16
->ntmFontSig
, sizeof(FONTSIGNATURE
));
456 /***********************************************************************
457 * CreateFontIndirectA (GDI32.@)
459 HFONT WINAPI
CreateFontIndirectA( const LOGFONTA
*plfA
)
464 FONT_LogFontAToW( plfA
, &lfW
);
465 return CreateFontIndirectW( &lfW
);
467 return CreateFontIndirectW( NULL
);
471 /***********************************************************************
472 * CreateFontIndirectW (GDI32.@)
474 HFONT WINAPI
CreateFontIndirectW( const LOGFONTW
*plf
)
481 if ((fontPtr
= GDI_AllocObject( sizeof(FONTOBJ
), FONT_MAGIC
, &hFont
, &font_funcs
)))
483 memcpy( &fontPtr
->logfont
, plf
, sizeof(LOGFONTW
) );
485 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
486 plf
->lfHeight
, plf
->lfWidth
,
487 plf
->lfEscapement
, plf
->lfOrientation
,
488 plf
->lfPitchAndFamily
,
489 debugstr_w(plf
->lfFaceName
),
490 plf
->lfWeight
> 400 ? "Bold" : "",
491 plf
->lfItalic
? "Italic" : "", hFont
);
493 if (plf
->lfEscapement
!= plf
->lfOrientation
) {
494 /* this should really depend on whether GM_ADVANCED is set */
495 fontPtr
->logfont
.lfOrientation
= fontPtr
->logfont
.lfEscapement
;
496 WARN("orientation angle %f set to "
497 "escapement angle %f for new font %04x\n",
498 plf
->lfOrientation
/10., plf
->lfEscapement
/10., hFont
);
500 GDI_ReleaseObj( hFont
);
503 else WARN("(NULL) => NULL\n");
508 /***********************************************************************
509 * CreateFont (GDI.56)
511 HFONT16 WINAPI
CreateFont16(INT16 height
, INT16 width
, INT16 esc
, INT16 orient
,
512 INT16 weight
, BYTE italic
, BYTE underline
,
513 BYTE strikeout
, BYTE charset
, BYTE outpres
,
514 BYTE clippres
, BYTE quality
, BYTE pitch
,
519 logfont
.lfHeight
= height
;
520 logfont
.lfWidth
= width
;
521 logfont
.lfEscapement
= esc
;
522 logfont
.lfOrientation
= orient
;
523 logfont
.lfWeight
= weight
;
524 logfont
.lfItalic
= italic
;
525 logfont
.lfUnderline
= underline
;
526 logfont
.lfStrikeOut
= strikeout
;
527 logfont
.lfCharSet
= charset
;
528 logfont
.lfOutPrecision
= outpres
;
529 logfont
.lfClipPrecision
= clippres
;
530 logfont
.lfQuality
= quality
;
531 logfont
.lfPitchAndFamily
= pitch
;
534 lstrcpynA(logfont
.lfFaceName
,name
,sizeof(logfont
.lfFaceName
));
536 logfont
.lfFaceName
[0] = '\0';
538 return CreateFontIndirect16( &logfont
);
541 /*************************************************************************
542 * CreateFontA (GDI32.@)
544 HFONT WINAPI
CreateFontA( INT height
, INT width
, INT esc
,
545 INT orient
, INT weight
, DWORD italic
,
546 DWORD underline
, DWORD strikeout
, DWORD charset
,
547 DWORD outpres
, DWORD clippres
, DWORD quality
,
548 DWORD pitch
, LPCSTR name
)
552 logfont
.lfHeight
= height
;
553 logfont
.lfWidth
= width
;
554 logfont
.lfEscapement
= esc
;
555 logfont
.lfOrientation
= orient
;
556 logfont
.lfWeight
= weight
;
557 logfont
.lfItalic
= italic
;
558 logfont
.lfUnderline
= underline
;
559 logfont
.lfStrikeOut
= strikeout
;
560 logfont
.lfCharSet
= charset
;
561 logfont
.lfOutPrecision
= outpres
;
562 logfont
.lfClipPrecision
= clippres
;
563 logfont
.lfQuality
= quality
;
564 logfont
.lfPitchAndFamily
= pitch
;
567 lstrcpynA(logfont
.lfFaceName
,name
,sizeof(logfont
.lfFaceName
));
569 logfont
.lfFaceName
[0] = '\0';
571 return CreateFontIndirectA( &logfont
);
574 /*************************************************************************
575 * CreateFontW (GDI32.@)
577 HFONT WINAPI
CreateFontW( INT height
, INT width
, INT esc
,
578 INT orient
, INT weight
, DWORD italic
,
579 DWORD underline
, DWORD strikeout
, DWORD charset
,
580 DWORD outpres
, DWORD clippres
, DWORD quality
,
581 DWORD pitch
, LPCWSTR name
)
585 logfont
.lfHeight
= height
;
586 logfont
.lfWidth
= width
;
587 logfont
.lfEscapement
= esc
;
588 logfont
.lfOrientation
= orient
;
589 logfont
.lfWeight
= weight
;
590 logfont
.lfItalic
= italic
;
591 logfont
.lfUnderline
= underline
;
592 logfont
.lfStrikeOut
= strikeout
;
593 logfont
.lfCharSet
= charset
;
594 logfont
.lfOutPrecision
= outpres
;
595 logfont
.lfClipPrecision
= clippres
;
596 logfont
.lfQuality
= quality
;
597 logfont
.lfPitchAndFamily
= pitch
;
600 lstrcpynW(logfont
.lfFaceName
, name
,
601 sizeof(logfont
.lfFaceName
) / sizeof(WCHAR
));
603 logfont
.lfFaceName
[0] = '\0';
605 return CreateFontIndirectW( &logfont
);
609 /***********************************************************************
612 * If the driver supports vector fonts we create a gdi font first and
613 * then call the driver to give it a chance to supply its own device
614 * font. If the driver wants to do this it returns TRUE and we can
615 * delete the gdi font, if the driver wants to use the gdi font it
616 * should return FALSE, to signal an error return GDI_ERROR. For
617 * drivers that don't support vector fonts they must supply their own
620 static HGDIOBJ
FONT_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
)
623 DC
*dc
= DC_GetDCPtr( hdc
);
627 if (dc
->hFont
!= handle
|| dc
->gdiFont
== NULL
)
629 if(GetDeviceCaps(dc
->hSelf
, TEXTCAPS
) & TC_VA_ABLE
)
630 dc
->gdiFont
= WineEngCreateFontInstance(dc
, handle
);
633 if (dc
->funcs
->pSelectFont
) ret
= dc
->funcs
->pSelectFont( dc
->physDev
, handle
);
635 if (ret
&& dc
->gdiFont
) dc
->gdiFont
= 0;
637 if (ret
== GDI_ERROR
)
638 ret
= 0; /* SelectObject returns 0 on error */
644 GDI_ReleaseObj( hdc
);
649 /***********************************************************************
652 static INT
FONT_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
657 FONT_LogFontWTo16( &font
->logfont
, &lf16
);
659 if (count
> sizeof(LOGFONT16
)) count
= sizeof(LOGFONT16
);
660 memcpy( buffer
, &lf16
, count
);
664 /***********************************************************************
667 static INT
FONT_GetObjectA( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
672 FONT_LogFontWToA( &font
->logfont
, &lfA
);
674 if (count
> sizeof(lfA
)) count
= sizeof(lfA
);
675 memcpy( buffer
, &lfA
, count
);
679 /***********************************************************************
682 static INT
FONT_GetObjectW( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
685 if (count
> sizeof(LOGFONTW
)) count
= sizeof(LOGFONTW
);
686 memcpy( buffer
, &font
->logfont
, count
);
691 /***********************************************************************
694 static BOOL
FONT_DeleteObject( HGDIOBJ handle
, void *obj
)
696 WineEngDestroyFontInstance( handle
);
697 return GDI_FreeObject( handle
, obj
);
701 /***********************************************************************
702 * FONT_EnumInstance16
704 * Called by the device driver layer to pass font info
705 * down to the application.
707 static INT
FONT_EnumInstance16( LPENUMLOGFONTEXW plf
, LPNEWTEXTMETRICEXW ptm
,
708 DWORD fType
, LPARAM lp
)
710 fontEnum16
*pfe
= (fontEnum16
*)lp
;
714 if( pfe
->lpLogFontParam
->lfCharSet
== DEFAULT_CHARSET
||
715 pfe
->lpLogFontParam
->lfCharSet
== plf
->elfLogFont
.lfCharSet
)
717 FONT_EnumLogFontExWTo16(plf
, pfe
->lpLogFont
);
718 FONT_NewTextMetricExWTo16(ptm
, pfe
->lpTextMetric
);
719 GDI_ReleaseObj( pfe
->hdc
); /* release the GDI lock */
721 ret
= FONT_CallTo16_word_llwl( pfe
->lpEnumFunc
, pfe
->segLogFont
, pfe
->segTextMetric
,
722 (UINT16
)fType
, (LPARAM
)pfe
->lpData
);
723 /* get the lock again and make sure the DC is still valid */
724 dc
= DC_GetDCPtr( pfe
->hdc
);
725 if (!dc
|| dc
!= pfe
->dc
|| dc
->physDev
!= pfe
->physDev
)
727 if (dc
) GDI_ReleaseObj( pfe
->hdc
);
728 pfe
->hdc
= 0; /* make sure we don't try to release it later on */
735 /***********************************************************************
738 static INT
FONT_EnumInstance( LPENUMLOGFONTEXW plf
, LPNEWTEXTMETRICEXW ptm
,
739 DWORD fType
, LPARAM lp
)
741 fontEnum32
*pfe
= (fontEnum32
*)lp
;
745 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
746 if( pfe
->lpLogFontParam
->lfCharSet
== DEFAULT_CHARSET
||
747 pfe
->lpLogFontParam
->lfCharSet
== plf
->elfLogFont
.lfCharSet
)
749 /* convert font metrics */
750 ENUMLOGFONTEXA logfont
;
751 NEWTEXTMETRICEXA tmA
;
753 pfe
->dwFlags
|= ENUM_CALLED
;
754 if (!(pfe
->dwFlags
& ENUM_UNICODE
))
756 FONT_EnumLogFontExWToA( plf
, &logfont
);
757 FONT_NewTextMetricExWToA( ptm
, &tmA
);
758 plf
= (LPENUMLOGFONTEXW
)&logfont
;
759 ptm
= (LPNEWTEXTMETRICEXW
)&tmA
;
761 GDI_ReleaseObj( pfe
->hdc
); /* release the GDI lock */
763 ret
= pfe
->lpEnumFunc( plf
, ptm
, fType
, pfe
->lpData
);
765 /* get the lock again and make sure the DC is still valid */
766 dc
= DC_GetDCPtr( pfe
->hdc
);
767 if (!dc
|| dc
!= pfe
->dc
|| dc
->physDev
!= pfe
->physDev
)
769 if (dc
) GDI_ReleaseObj( pfe
->hdc
);
770 pfe
->hdc
= 0; /* make sure we don't try to release it later on */
777 /***********************************************************************
778 * EnumFontFamiliesEx (GDI.613)
780 INT16 WINAPI
EnumFontFamiliesEx16( HDC16 hDC
, LPLOGFONT16 plf
,
781 FONTENUMPROCEX16 efproc
, LPARAM lParam
,
786 DC
* dc
= DC_GetDCPtr( hDC
);
791 fe16
.physDev
= dc
->physDev
;
793 if (dc
->funcs
->pEnumDeviceFonts
)
795 NEWTEXTMETRICEX16 tm16
;
796 ENUMLOGFONTEX16 lf16
;
798 FONT_LogFont16ToW(plf
, &lfW
);
800 fe16
.lpLogFontParam
= plf
;
801 fe16
.lpEnumFunc
= efproc
;
802 fe16
.lpData
= lParam
;
803 fe16
.lpTextMetric
= &tm16
;
804 fe16
.lpLogFont
= &lf16
;
805 fe16
.segTextMetric
= MapLS( &tm16
);
806 fe16
.segLogFont
= MapLS( &lf16
);
808 retVal
= dc
->funcs
->pEnumDeviceFonts( dc
->physDev
, &lfW
,
809 FONT_EnumInstance16
, (LPARAM
)&fe16
);
810 UnMapLS( fe16
.segTextMetric
);
811 UnMapLS( fe16
.segLogFont
);
813 if (fe16
.hdc
) GDI_ReleaseObj( fe16
.hdc
);
817 /***********************************************************************
818 * FONT_EnumFontFamiliesEx
820 static INT
FONT_EnumFontFamiliesEx( HDC hDC
, LPLOGFONTW plf
,
821 FONTENUMPROCEXW efproc
,
822 LPARAM lParam
, DWORD dwUnicode
)
825 DC
*dc
= DC_GetDCPtr( hDC
);
831 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf
->lfFaceName
),
833 fe32
.lpLogFontParam
= plf
;
834 fe32
.lpEnumFunc
= efproc
;
835 fe32
.lpData
= lParam
;
836 fe32
.dwFlags
= dwUnicode
;
839 fe32
.physDev
= dc
->physDev
;
841 enum_gdi_fonts
= GetDeviceCaps(hDC
, TEXTCAPS
) & TC_VA_ABLE
;
843 if (!dc
->funcs
->pEnumDeviceFonts
&& !enum_gdi_fonts
)
850 ret
= WineEngEnumFonts( plf
, FONT_EnumInstance
, (LPARAM
)&fe32
);
851 fe32
.dwFlags
&= ~ENUM_CALLED
;
852 if (ret
&& dc
->funcs
->pEnumDeviceFonts
) {
853 ret2
= dc
->funcs
->pEnumDeviceFonts( dc
->physDev
, plf
, FONT_EnumInstance
, (LPARAM
)&fe32
);
854 if(fe32
.dwFlags
& ENUM_CALLED
) /* update ret iff a font gets enumed */
858 if (fe32
.hdc
) GDI_ReleaseObj( fe32
.hdc
);
862 /***********************************************************************
863 * EnumFontFamiliesExW (GDI32.@)
865 INT WINAPI
EnumFontFamiliesExW( HDC hDC
, LPLOGFONTW plf
,
866 FONTENUMPROCEXW efproc
,
867 LPARAM lParam
, DWORD dwFlags
)
869 return FONT_EnumFontFamiliesEx( hDC
, plf
, efproc
, lParam
, ENUM_UNICODE
);
872 /***********************************************************************
873 * EnumFontFamiliesExA (GDI32.@)
875 INT WINAPI
EnumFontFamiliesExA( HDC hDC
, LPLOGFONTA plf
,
876 FONTENUMPROCEXA efproc
,
877 LPARAM lParam
, DWORD dwFlags
)
880 FONT_LogFontAToW( plf
, &lfW
);
882 return FONT_EnumFontFamiliesEx( hDC
, &lfW
,
883 (FONTENUMPROCEXW
)efproc
, lParam
, 0);
886 /***********************************************************************
887 * EnumFontFamilies (GDI.330)
889 INT16 WINAPI
EnumFontFamilies16( HDC16 hDC
, LPCSTR lpFamily
,
890 FONTENUMPROC16 efproc
, LPARAM lpData
)
894 lf
.lfCharSet
= DEFAULT_CHARSET
;
895 if( lpFamily
) lstrcpynA( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
896 else lf
.lfFaceName
[0] = '\0';
898 return EnumFontFamiliesEx16( hDC
, &lf
, efproc
, lpData
, 0 );
901 /***********************************************************************
902 * EnumFontFamiliesA (GDI32.@)
904 INT WINAPI
EnumFontFamiliesA( HDC hDC
, LPCSTR lpFamily
,
905 FONTENUMPROCA efproc
, LPARAM lpData
)
909 lf
.lfCharSet
= DEFAULT_CHARSET
;
910 if( lpFamily
) lstrcpynA( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
911 else lf
.lfFaceName
[0] = lf
.lfFaceName
[1] = '\0';
913 return EnumFontFamiliesExA( hDC
, &lf
, (FONTENUMPROCEXA
)efproc
, lpData
, 0 );
916 /***********************************************************************
917 * EnumFontFamiliesW (GDI32.@)
919 INT WINAPI
EnumFontFamiliesW( HDC hDC
, LPCWSTR lpFamily
,
920 FONTENUMPROCW efproc
, LPARAM lpData
)
924 lf
.lfCharSet
= DEFAULT_CHARSET
;
925 if( lpFamily
) lstrcpynW( lf
.lfFaceName
, lpFamily
, LF_FACESIZE
);
926 else lf
.lfFaceName
[0] = 0;
928 return EnumFontFamiliesExW( hDC
, &lf
, (FONTENUMPROCEXW
)efproc
, lpData
, 0 );
931 /***********************************************************************
934 INT16 WINAPI
EnumFonts16( HDC16 hDC
, LPCSTR lpName
, FONTENUMPROC16 efproc
,
937 return EnumFontFamilies16( hDC
, lpName
, (FONTENUMPROCEX16
)efproc
, lpData
);
940 /***********************************************************************
941 * EnumFontsA (GDI32.@)
943 INT WINAPI
EnumFontsA( HDC hDC
, LPCSTR lpName
, FONTENUMPROCA efproc
,
946 return EnumFontFamiliesA( hDC
, lpName
, efproc
, lpData
);
949 /***********************************************************************
950 * EnumFontsW (GDI32.@)
952 INT WINAPI
EnumFontsW( HDC hDC
, LPCWSTR lpName
, FONTENUMPROCW efproc
,
955 return EnumFontFamiliesW( hDC
, lpName
, efproc
, lpData
);
959 /***********************************************************************
960 * GetTextCharacterExtra (GDI32.@)
962 INT WINAPI
GetTextCharacterExtra( HDC hdc
)
965 DC
*dc
= DC_GetDCPtr( hdc
);
967 ret
= abs( (dc
->charExtra
* dc
->wndExtX
+ dc
->vportExtX
/ 2)
969 GDI_ReleaseObj( hdc
);
974 /***********************************************************************
975 * SetTextCharacterExtra (GDI32.@)
977 INT WINAPI
SetTextCharacterExtra( HDC hdc
, INT extra
)
980 DC
* dc
= DC_GetDCPtr( hdc
);
982 if (dc
->funcs
->pSetTextCharacterExtra
)
983 prev
= dc
->funcs
->pSetTextCharacterExtra( dc
->physDev
, extra
);
986 extra
= (extra
* dc
->vportExtX
+ dc
->wndExtX
/ 2) / dc
->wndExtX
;
987 prev
= (dc
->charExtra
* dc
->wndExtX
+ dc
->vportExtX
/ 2) / dc
->vportExtX
;
988 dc
->charExtra
= abs(extra
);
990 GDI_ReleaseObj( hdc
);
995 /***********************************************************************
996 * SetTextJustification (GDI32.@)
998 BOOL WINAPI
SetTextJustification( HDC hdc
, INT extra
, INT breaks
)
1001 DC
* dc
= DC_GetDCPtr( hdc
);
1002 if (!dc
) return FALSE
;
1003 if (dc
->funcs
->pSetTextJustification
)
1004 ret
= dc
->funcs
->pSetTextJustification( dc
->physDev
, extra
, breaks
);
1007 extra
= abs((extra
* dc
->vportExtX
+ dc
->wndExtX
/ 2) / dc
->wndExtX
);
1008 if (!extra
) breaks
= 0;
1009 dc
->breakTotalExtra
= extra
;
1010 dc
->breakCount
= breaks
;
1013 dc
->breakExtra
= extra
/ breaks
;
1014 dc
->breakRem
= extra
- (dc
->breakCount
* dc
->breakExtra
);
1022 GDI_ReleaseObj( hdc
);
1027 /***********************************************************************
1028 * GetTextFaceA (GDI32.@)
1030 INT WINAPI
GetTextFaceA( HDC hdc
, INT count
, LPSTR name
)
1032 INT res
= GetTextFaceW(hdc
, 0, NULL
);
1033 LPWSTR nameW
= HeapAlloc( GetProcessHeap(), 0, res
* 2 );
1034 GetTextFaceW( hdc
, res
, nameW
);
1037 res
= WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, name
, count
,
1040 res
= WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, NULL
, 0, NULL
, NULL
);
1041 HeapFree( GetProcessHeap(), 0, nameW
);
1045 /***********************************************************************
1046 * GetTextFaceW (GDI32.@)
1048 INT WINAPI
GetTextFaceW( HDC hdc
, INT count
, LPWSTR name
)
1053 DC
* dc
= DC_GetDCPtr( hdc
);
1057 ret
= WineEngGetTextFace(dc
->gdiFont
, count
, name
);
1058 else if ((font
= (FONTOBJ
*) GDI_GetObjPtr( dc
->hFont
, FONT_MAGIC
)))
1062 lstrcpynW( name
, font
->logfont
.lfFaceName
, count
);
1063 ret
= strlenW(name
);
1065 else ret
= strlenW(font
->logfont
.lfFaceName
) + 1;
1066 GDI_ReleaseObj( dc
->hFont
);
1068 GDI_ReleaseObj( hdc
);
1073 /***********************************************************************
1074 * GetTextExtentPoint32A (GDI32.@)
1076 BOOL WINAPI
GetTextExtentPoint32A( HDC hdc
, LPCSTR str
, INT count
,
1081 LPWSTR p
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
1084 ret
= GetTextExtentPoint32W( hdc
, p
, wlen
, size
);
1085 HeapFree( GetProcessHeap(), 0, p
);
1088 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1089 hdc
, debugstr_an (str
, count
), count
, size
, size
->cx
, size
->cy
);
1094 /***********************************************************************
1095 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1097 * Computes width and height of the specified string.
1103 BOOL WINAPI
GetTextExtentPoint32W(
1104 HDC hdc
, /* [in] Handle of device context */
1105 LPCWSTR str
, /* [in] Address of text string */
1106 INT count
, /* [in] Number of characters in string */
1107 LPSIZE size
) /* [out] Address of structure for string size */
1110 DC
* dc
= DC_GetDCPtr( hdc
);
1111 if (!dc
) return FALSE
;
1114 ret
= WineEngGetTextExtentPoint(dc
->gdiFont
, str
, count
, size
);
1115 size
->cx
= abs(INTERNAL_XDSTOWS(dc
, size
->cx
));
1116 size
->cy
= abs(INTERNAL_YDSTOWS(dc
, size
->cy
));
1118 else if(dc
->funcs
->pGetTextExtentPoint
)
1119 ret
= dc
->funcs
->pGetTextExtentPoint( dc
->physDev
, str
, count
, size
);
1121 GDI_ReleaseObj( hdc
);
1123 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1124 hdc
, debugstr_wn (str
, count
), count
, size
, size
->cx
, size
->cy
);
1128 /***********************************************************************
1129 * GetTextExtentPointI [GDI32.@]
1131 * Computes width and height of the array of glyph indices.
1137 BOOL WINAPI
GetTextExtentPointI(
1138 HDC hdc
, /* [in] Handle of device context */
1139 const WORD
*indices
, /* [in] Address of glyph index array */
1140 INT count
, /* [in] Number of glyphs in array */
1141 LPSIZE size
) /* [out] Address of structure for string size */
1144 DC
* dc
= DC_GetDCPtr( hdc
);
1145 if (!dc
) return FALSE
;
1148 ret
= WineEngGetTextExtentPointI(dc
->gdiFont
, indices
, count
, size
);
1149 size
->cx
= abs(INTERNAL_XDSTOWS(dc
, size
->cx
));
1150 size
->cy
= abs(INTERNAL_YDSTOWS(dc
, size
->cy
));
1152 else if(dc
->funcs
->pGetTextExtentPoint
) {
1153 FIXME("calling GetTextExtentPoint\n");
1154 ret
= dc
->funcs
->pGetTextExtentPoint( dc
->physDev
, (LPCWSTR
)indices
, count
, size
);
1157 GDI_ReleaseObj( hdc
);
1159 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1160 hdc
, indices
, count
, size
, size
->cx
, size
->cy
);
1165 /***********************************************************************
1166 * GetTextExtentPointA (GDI32.@)
1168 BOOL WINAPI
GetTextExtentPointA( HDC hdc
, LPCSTR str
, INT count
,
1171 TRACE("not bug compatible.\n");
1172 return GetTextExtentPoint32A( hdc
, str
, count
, size
);
1175 /***********************************************************************
1176 * GetTextExtentPointW (GDI32.@)
1178 BOOL WINAPI
GetTextExtentPointW( HDC hdc
, LPCWSTR str
, INT count
,
1181 TRACE("not bug compatible.\n");
1182 return GetTextExtentPoint32W( hdc
, str
, count
, size
);
1186 /***********************************************************************
1187 * GetTextExtentExPointA (GDI32.@)
1189 BOOL WINAPI
GetTextExtentExPointA( HDC hdc
, LPCSTR str
, INT count
,
1190 INT maxExt
, LPINT lpnFit
,
1191 LPINT alpDx
, LPSIZE size
)
1195 LPWSTR p
= FONT_mbtowc( hdc
, str
, count
, &wlen
, NULL
);
1196 ret
= GetTextExtentExPointW( hdc
, p
, wlen
, maxExt
, lpnFit
, alpDx
, size
);
1197 HeapFree( GetProcessHeap(), 0, p
);
1202 /***********************************************************************
1203 * GetTextExtentExPointW (GDI32.@)
1205 * Return the size of the string as it would be if it was output properly by
1208 * This should include
1209 * - Intercharacter spacing
1210 * - justification spacing (not yet done)
1211 * - kerning? see below
1213 * Kerning. Since kerning would be carried out by the rendering code it should
1214 * be done by the driver. However they don't support it yet. Also I am not
1215 * yet persuaded that (certainly under Win95) any kerning is actually done.
1217 * str: According to MSDN this should be null-terminated. That is not true; a
1218 * null will not terminate it early.
1219 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1220 * than count. I have seen it be either the size of the full string or
1221 * 1 less than the size of the full string. I have not seen it bear any
1222 * resemblance to the portion that would fit.
1223 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1224 * trailing intercharacter spacing and any trailing justification.
1227 * Currently we do this by measuring each character etc. We should do it by
1228 * passing the request to the driver, perhaps by extending the
1229 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1230 * thinking about kerning issues and rounding issues in the justification.
1233 BOOL WINAPI
GetTextExtentExPointW( HDC hdc
, LPCWSTR str
, INT count
,
1234 INT maxExt
, LPINT lpnFit
,
1235 LPINT alpDx
, LPSIZE size
)
1237 int index
, nFit
, extent
;
1241 TRACE("(%08x, %s, %d)\n",hdc
,debugstr_wn(str
,count
),maxExt
);
1243 size
->cx
= size
->cy
= nFit
= extent
= 0;
1244 for(index
= 0; index
< count
; index
++)
1246 if(!GetTextExtentPoint32W( hdc
, str
, 1, &tSize
)) goto done
;
1247 /* GetTextExtentPoint includes intercharacter spacing. */
1248 /* FIXME - justification needs doing yet. Remember that the base
1249 * data will not be in logical coordinates.
1252 if( !lpnFit
|| extent
<= maxExt
)
1253 /* It is allowed to be equal. */
1256 if( alpDx
) alpDx
[index
] = extent
;
1258 if( tSize
.cy
> size
->cy
) size
->cy
= tSize
.cy
;
1262 if(lpnFit
) *lpnFit
= nFit
;
1265 TRACE("returning %d %ld x %ld\n",nFit
,size
->cx
,size
->cy
);
1271 /***********************************************************************
1272 * GetTextMetricsA (GDI32.@)
1274 BOOL WINAPI
GetTextMetricsA( HDC hdc
, TEXTMETRICA
*metrics
)
1278 if (!GetTextMetricsW( hdc
, &tm32
)) return FALSE
;
1279 FONT_TextMetricWToA( &tm32
, metrics
);
1283 /***********************************************************************
1284 * GetTextMetricsW (GDI32.@)
1286 BOOL WINAPI
GetTextMetricsW( HDC hdc
, TEXTMETRICW
*metrics
)
1289 DC
* dc
= DC_GetDCPtr( hdc
);
1290 if (!dc
) return FALSE
;
1293 ret
= WineEngGetTextMetrics(dc
->gdiFont
, metrics
);
1294 else if (dc
->funcs
->pGetTextMetrics
)
1295 ret
= dc
->funcs
->pGetTextMetrics( dc
->physDev
, metrics
);
1299 /* device layer returns values in device units
1300 * therefore we have to convert them to logical */
1302 #define WDPTOLP(x) ((x<0)? \
1303 (-abs(INTERNAL_XDSTOWS(dc, (x)))): \
1304 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1305 #define HDPTOLP(y) ((y<0)? \
1306 (-abs(INTERNAL_YDSTOWS(dc, (y)))): \
1307 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1309 metrics
->tmHeight
= HDPTOLP(metrics
->tmHeight
);
1310 metrics
->tmAscent
= HDPTOLP(metrics
->tmAscent
);
1311 metrics
->tmDescent
= HDPTOLP(metrics
->tmDescent
);
1312 metrics
->tmInternalLeading
= HDPTOLP(metrics
->tmInternalLeading
);
1313 metrics
->tmExternalLeading
= HDPTOLP(metrics
->tmExternalLeading
);
1314 metrics
->tmAveCharWidth
= WDPTOLP(metrics
->tmAveCharWidth
);
1315 metrics
->tmMaxCharWidth
= WDPTOLP(metrics
->tmMaxCharWidth
);
1316 metrics
->tmOverhang
= WDPTOLP(metrics
->tmOverhang
);
1319 TRACE("text metrics:\n"
1320 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1321 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1322 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1323 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1324 " PitchAndFamily = %02x\n"
1325 " --------------------\n"
1326 " InternalLeading = %li\n"
1330 metrics
->tmWeight
, metrics
->tmFirstChar
, metrics
->tmAveCharWidth
,
1331 metrics
->tmItalic
, metrics
->tmLastChar
, metrics
->tmMaxCharWidth
,
1332 metrics
->tmUnderlined
, metrics
->tmDefaultChar
, metrics
->tmOverhang
,
1333 metrics
->tmStruckOut
, metrics
->tmBreakChar
, metrics
->tmCharSet
,
1334 metrics
->tmPitchAndFamily
,
1335 metrics
->tmInternalLeading
,
1338 metrics
->tmHeight
);
1340 GDI_ReleaseObj( hdc
);
1345 /***********************************************************************
1346 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1349 * lpOTM should be LPOUTLINETEXTMETRIC
1352 * Success: Non-zero or size of required buffer
1355 UINT16 WINAPI
GetOutlineTextMetrics16(
1356 HDC16 hdc
, /* [in] Handle of device context */
1357 UINT16 cbData
, /* [in] Size of metric data array */
1358 LPOUTLINETEXTMETRIC16 lpOTM
) /* [out] Address of metric data array */
1360 FIXME("(%04x,%04x,%p): stub\n", hdc
,cbData
,lpOTM
);
1365 /***********************************************************************
1366 * GetOutlineTextMetricsA (GDI32.@)
1367 * Gets metrics for TrueType fonts.
1371 * Success: Non-zero or size of required buffer
1374 UINT WINAPI
GetOutlineTextMetricsA(
1375 HDC hdc
, /* [in] Handle of device context */
1376 UINT cbData
, /* [in] Size of metric data array */
1377 LPOUTLINETEXTMETRICA lpOTM
) /* [out] Address of metric data array */
1379 char buf
[512], *ptr
;
1381 OUTLINETEXTMETRICW
*lpOTMW
= (OUTLINETEXTMETRICW
*)buf
;
1384 if((ret
= GetOutlineTextMetricsW(hdc
, sizeof(buf
), lpOTMW
)) == 0) {
1385 if((ret
= GetOutlineTextMetricsW(hdc
, 0, NULL
)) == 0)
1387 lpOTMW
= HeapAlloc(GetProcessHeap(), 0, ret
);
1388 GetOutlineTextMetricsW(hdc
, ret
, lpOTMW
);
1391 needed
= sizeof(OUTLINETEXTMETRICA
);
1392 if(lpOTMW
->otmpFamilyName
)
1393 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1394 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFamilyName
), -1,
1395 NULL
, 0, NULL
, NULL
);
1396 if(lpOTMW
->otmpFaceName
)
1397 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1398 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFaceName
), -1,
1399 NULL
, 0, NULL
, NULL
);
1400 if(lpOTMW
->otmpStyleName
)
1401 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1402 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpStyleName
), -1,
1403 NULL
, 0, NULL
, NULL
);
1404 if(lpOTMW
->otmpFullName
)
1405 needed
+= WideCharToMultiByte(CP_ACP
, 0,
1406 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFullName
), -1,
1407 NULL
, 0, NULL
, NULL
);
1414 if(needed
> cbData
) {
1420 lpOTM
->otmSize
= needed
;
1421 FONT_TextMetricWToA( &lpOTMW
->otmTextMetrics
, &lpOTM
->otmTextMetrics
);
1422 lpOTM
->otmFiller
= 0;
1423 lpOTM
->otmPanoseNumber
= lpOTMW
->otmPanoseNumber
;
1424 lpOTM
->otmfsSelection
= lpOTMW
->otmfsSelection
;
1425 lpOTM
->otmfsType
= lpOTMW
->otmfsType
;
1426 lpOTM
->otmsCharSlopeRise
= lpOTMW
->otmsCharSlopeRise
;
1427 lpOTM
->otmsCharSlopeRun
= lpOTMW
->otmsCharSlopeRun
;
1428 lpOTM
->otmItalicAngle
= lpOTMW
->otmItalicAngle
;
1429 lpOTM
->otmEMSquare
= lpOTMW
->otmEMSquare
;
1430 lpOTM
->otmAscent
= lpOTMW
->otmAscent
;
1431 lpOTM
->otmDescent
= lpOTMW
->otmDescent
;
1432 lpOTM
->otmLineGap
= lpOTMW
->otmLineGap
;
1433 lpOTM
->otmsCapEmHeight
= lpOTMW
->otmsCapEmHeight
;
1434 lpOTM
->otmsXHeight
= lpOTMW
->otmsXHeight
;
1435 lpOTM
->otmrcFontBox
= lpOTMW
->otmrcFontBox
;
1436 lpOTM
->otmMacAscent
= lpOTMW
->otmMacAscent
;
1437 lpOTM
->otmMacDescent
= lpOTMW
->otmMacDescent
;
1438 lpOTM
->otmMacLineGap
= lpOTMW
->otmMacLineGap
;
1439 lpOTM
->otmusMinimumPPEM
= lpOTMW
->otmusMinimumPPEM
;
1440 lpOTM
->otmptSubscriptSize
= lpOTMW
->otmptSubscriptSize
;
1441 lpOTM
->otmptSubscriptOffset
= lpOTMW
->otmptSubscriptOffset
;
1442 lpOTM
->otmptSuperscriptSize
= lpOTMW
->otmptSuperscriptSize
;
1443 lpOTM
->otmptSuperscriptOffset
= lpOTMW
->otmptSuperscriptOffset
;
1444 lpOTM
->otmsStrikeoutSize
= lpOTMW
->otmsStrikeoutSize
;
1445 lpOTM
->otmsStrikeoutPosition
= lpOTMW
->otmsStrikeoutPosition
;
1446 lpOTM
->otmsUnderscoreSize
= lpOTMW
->otmsUnderscoreSize
;
1447 lpOTM
->otmsUnderscorePosition
= lpOTMW
->otmsUnderscorePosition
;
1450 ptr
= (char*)(lpOTM
+ 1);
1451 left
= needed
- sizeof(*lpOTM
);
1453 if(lpOTMW
->otmpFamilyName
) {
1454 lpOTM
->otmpFamilyName
= (LPSTR
)(ptr
- (char*)lpOTM
);
1455 len
= WideCharToMultiByte(CP_ACP
, 0,
1456 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFamilyName
), -1,
1457 ptr
, left
, NULL
, NULL
);
1461 lpOTM
->otmpFamilyName
= 0;
1463 if(lpOTMW
->otmpFaceName
) {
1464 lpOTM
->otmpFaceName
= (LPSTR
)(ptr
- (char*)lpOTM
);
1465 len
= WideCharToMultiByte(CP_ACP
, 0,
1466 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFaceName
), -1,
1467 ptr
, left
, NULL
, NULL
);
1471 lpOTM
->otmpFaceName
= 0;
1473 if(lpOTMW
->otmpStyleName
) {
1474 lpOTM
->otmpStyleName
= (LPSTR
)(ptr
- (char*)lpOTM
);
1475 len
= WideCharToMultiByte(CP_ACP
, 0,
1476 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpStyleName
), -1,
1477 ptr
, left
, NULL
, NULL
);
1481 lpOTM
->otmpStyleName
= 0;
1483 if(lpOTMW
->otmpFullName
) {
1484 lpOTM
->otmpFullName
= (LPSTR
)(ptr
- (char*)lpOTM
);
1485 len
= WideCharToMultiByte(CP_ACP
, 0,
1486 (WCHAR
*)((char*)lpOTMW
+ (ptrdiff_t)lpOTMW
->otmpFullName
), -1,
1487 ptr
, left
, NULL
, NULL
);
1490 lpOTM
->otmpFullName
= 0;
1497 if(lpOTMW
!= (OUTLINETEXTMETRICW
*)buf
)
1498 HeapFree(GetProcessHeap(), 0, lpOTMW
);
1504 /***********************************************************************
1505 * GetOutlineTextMetricsW [GDI32.@]
1507 UINT WINAPI
GetOutlineTextMetricsW(
1508 HDC hdc
, /* [in] Handle of device context */
1509 UINT cbData
, /* [in] Size of metric data array */
1510 LPOUTLINETEXTMETRICW lpOTM
) /* [out] Address of metric data array */
1512 DC
*dc
= DC_GetDCPtr( hdc
);
1515 TRACE("(%d,%d,%p)\n", hdc
, cbData
, lpOTM
);
1519 ret
= WineEngGetOutlineTextMetrics(dc
->gdiFont
, cbData
, lpOTM
);
1521 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1522 but really this should just be a return 0. */
1524 ret
= sizeof(*lpOTM
);
1529 memset(lpOTM
, 0, ret
);
1530 lpOTM
->otmSize
= sizeof(*lpOTM
);
1531 GetTextMetricsW(hdc
, &lpOTM
->otmTextMetrics
);
1533 Further fill of the structure not implemented,
1534 Needs real values for the structure members
1539 GDI_ReleaseObj(hdc
);
1544 /***********************************************************************
1545 * GetCharWidthW (GDI32.@)
1546 * GetCharWidth32W (GDI32.@)
1548 BOOL WINAPI
GetCharWidth32W( HDC hdc
, UINT firstChar
, UINT lastChar
,
1553 DC
* dc
= DC_GetDCPtr( hdc
);
1554 if (!dc
) return FALSE
;
1557 ret
= WineEngGetCharWidth( dc
->gdiFont
, firstChar
, lastChar
, buffer
);
1558 else if (dc
->funcs
->pGetCharWidth
)
1559 ret
= dc
->funcs
->pGetCharWidth( dc
->physDev
, firstChar
, lastChar
, buffer
);
1563 /* convert device units to logical */
1565 extra
= dc
->vportExtX
>> 1;
1566 for( i
= firstChar
; i
<= lastChar
; i
++, buffer
++ )
1567 *buffer
= (*buffer
* dc
->wndExtX
+ extra
) / dc
->vportExtX
;
1570 GDI_ReleaseObj( hdc
);
1575 /***********************************************************************
1576 * GetCharWidthA (GDI32.@)
1577 * GetCharWidth32A (GDI32.@)
1579 BOOL WINAPI
GetCharWidth32A( HDC hdc
, UINT firstChar
, UINT lastChar
,
1582 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
1587 if(count
<= 0) return FALSE
;
1589 str
= HeapAlloc(GetProcessHeap(), 0, count
);
1590 for(i
= 0; i
< count
; i
++)
1591 str
[i
] = (BYTE
)(firstChar
+ i
);
1593 wstr
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
1595 for(i
= 0; i
< wlen
; i
++)
1597 if(!GetCharWidth32W(hdc
, wstr
[i
], wstr
[i
], buffer
))
1605 HeapFree(GetProcessHeap(), 0, str
);
1606 HeapFree(GetProcessHeap(), 0, wstr
);
1612 /* FIXME: all following APIs ******************************************/
1615 /***********************************************************************
1616 * SetMapperFlags (GDI32.@)
1618 DWORD WINAPI
SetMapperFlags( HDC hDC
, DWORD dwFlag
)
1620 DC
*dc
= DC_GetDCPtr( hDC
);
1623 if(dc
->funcs
->pSetMapperFlags
)
1624 ret
= dc
->funcs
->pSetMapperFlags( dc
->physDev
, dwFlag
);
1626 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC
, dwFlag
);
1627 GDI_ReleaseObj( hDC
);
1631 /***********************************************************************
1632 * GetAspectRatioFilterEx (GDI.486)
1634 BOOL16 WINAPI
GetAspectRatioFilterEx16( HDC16 hdc
, LPSIZE16 pAspectRatio
)
1636 FIXME("(%04x, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
1640 /***********************************************************************
1641 * GetAspectRatioFilterEx (GDI32.@)
1643 BOOL WINAPI
GetAspectRatioFilterEx( HDC hdc
, LPSIZE pAspectRatio
)
1645 FIXME("(%04x, %p): -- Empty Stub !\n", hdc
, pAspectRatio
);
1650 /***********************************************************************
1651 * GetCharABCWidthsA (GDI32.@)
1653 BOOL WINAPI
GetCharABCWidthsA(HDC hdc
, UINT firstChar
, UINT lastChar
,
1656 INT i
, wlen
, count
= (INT
)(lastChar
- firstChar
+ 1);
1661 if(count
<= 0) return FALSE
;
1663 str
= HeapAlloc(GetProcessHeap(), 0, count
);
1664 for(i
= 0; i
< count
; i
++)
1665 str
[i
] = (BYTE
)(firstChar
+ i
);
1667 wstr
= FONT_mbtowc(hdc
, str
, count
, &wlen
, NULL
);
1669 for(i
= 0; i
< wlen
; i
++)
1671 if(!GetCharABCWidthsW(hdc
, wstr
[i
], wstr
[i
], abc
))
1679 HeapFree(GetProcessHeap(), 0, str
);
1680 HeapFree(GetProcessHeap(), 0, wstr
);
1686 /******************************************************************************
1687 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1690 * hdc [I] Handle of device context
1691 * firstChar [I] First character in range to query
1692 * lastChar [I] Last character in range to query
1693 * abc [O] Address of character-width structure
1696 * Only works with TrueType fonts
1702 BOOL WINAPI
GetCharABCWidthsW( HDC hdc
, UINT firstChar
, UINT lastChar
,
1705 DC
*dc
= DC_GetDCPtr(hdc
);
1711 for (i
=firstChar
;i
<=lastChar
;i
++) {
1712 GetGlyphOutlineW(hdc
, i
, GGO_METRICS
, &gm
, 0, NULL
, NULL
);
1713 abc
[i
-firstChar
].abcA
= gm
.gmptGlyphOrigin
.x
;
1714 abc
[i
-firstChar
].abcB
= gm
.gmBlackBoxX
;
1715 abc
[i
-firstChar
].abcC
= gm
.gmCellIncX
- gm
.gmptGlyphOrigin
.x
- gm
.gmBlackBoxX
;
1719 GDI_ReleaseObj(hdc
);
1724 /***********************************************************************
1725 * GetGlyphOutline (GDI.309)
1727 DWORD WINAPI
GetGlyphOutline16( HDC16 hdc
, UINT16 uChar
, UINT16 fuFormat
,
1728 LPGLYPHMETRICS16 lpgm
, DWORD cbBuffer
,
1729 LPVOID lpBuffer
, const MAT2
*lpmat2
)
1731 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1732 hdc
, uChar
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
, lpmat2
);
1733 return (DWORD
)-1; /* failure */
1737 /***********************************************************************
1738 * GetGlyphOutlineA (GDI32.@)
1740 DWORD WINAPI
GetGlyphOutlineA( HDC hdc
, UINT uChar
, UINT fuFormat
,
1741 LPGLYPHMETRICS lpgm
, DWORD cbBuffer
,
1742 LPVOID lpBuffer
, const MAT2
*lpmat2
)
1748 if(!(fuFormat
& GGO_GLYPH_INDEX
)) {
1749 p
= FONT_mbtowc(hdc
, (char*)&uChar
, 1, NULL
, NULL
);
1753 ret
= GetGlyphOutlineW(hdc
, c
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
,
1756 HeapFree(GetProcessHeap(), 0, p
);
1760 /***********************************************************************
1761 * GetGlyphOutlineW (GDI32.@)
1763 DWORD WINAPI
GetGlyphOutlineW( HDC hdc
, UINT uChar
, UINT fuFormat
,
1764 LPGLYPHMETRICS lpgm
, DWORD cbBuffer
,
1765 LPVOID lpBuffer
, const MAT2
*lpmat2
)
1767 DC
*dc
= DC_GetDCPtr(hdc
);
1770 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1771 hdc
, uChar
, fuFormat
, lpgm
, cbBuffer
, lpBuffer
, lpmat2
);
1773 if(!dc
) return GDI_ERROR
;
1776 ret
= WineEngGetGlyphOutline(dc
->gdiFont
, uChar
, fuFormat
, lpgm
,
1777 cbBuffer
, lpBuffer
, lpmat2
);
1781 GDI_ReleaseObj(hdc
);
1786 /***********************************************************************
1787 * CreateScalableFontResourceA (GDI32.@)
1789 BOOL WINAPI
CreateScalableFontResourceA( DWORD fHidden
,
1790 LPCSTR lpszResourceFile
,
1791 LPCSTR lpszFontFile
,
1792 LPCSTR lpszCurrentPath
)
1796 /* fHidden=1 - only visible for the calling app, read-only, not
1797 * enumbered with EnumFonts/EnumFontFamilies
1798 * lpszCurrentPath can be NULL
1800 FIXME("(%ld,%s,%s,%s): stub\n",
1801 fHidden
, debugstr_a(lpszResourceFile
), debugstr_a(lpszFontFile
),
1802 debugstr_a(lpszCurrentPath
) );
1804 /* If the output file already exists, return the ERROR_FILE_EXISTS error as specified in MSDN */
1805 if ((f
= CreateFileA(lpszResourceFile
, 0, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, 0)) != INVALID_HANDLE_VALUE
) {
1807 SetLastError(ERROR_FILE_EXISTS
);
1810 return FALSE
; /* create failed */
1813 /***********************************************************************
1814 * CreateScalableFontResourceW (GDI32.@)
1816 BOOL WINAPI
CreateScalableFontResourceW( DWORD fHidden
,
1817 LPCWSTR lpszResourceFile
,
1818 LPCWSTR lpszFontFile
,
1819 LPCWSTR lpszCurrentPath
)
1821 FIXME("(%ld,%p,%p,%p): stub\n",
1822 fHidden
, lpszResourceFile
, lpszFontFile
, lpszCurrentPath
);
1823 return FALSE
; /* create failed */
1827 /*************************************************************************
1828 * GetRasterizerCaps (GDI32.@)
1830 BOOL WINAPI
GetRasterizerCaps( LPRASTERIZER_STATUS lprs
, UINT cbNumBytes
)
1832 lprs
->nSize
= sizeof(RASTERIZER_STATUS
);
1833 lprs
->wFlags
= TT_AVAILABLE
|TT_ENABLED
;
1834 lprs
->nLanguageID
= 0;
1839 /*************************************************************************
1840 * GetKerningPairsA (GDI32.@)
1842 DWORD WINAPI
GetKerningPairsA( HDC hDC
, DWORD cPairs
, LPKERNINGPAIR lpKerningPairs
)
1845 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC
, cPairs
, lpKerningPairs
);
1846 for (i
= 0; i
< cPairs
; i
++)
1847 lpKerningPairs
[i
].iKernAmount
= 0;
1852 /*************************************************************************
1853 * GetKerningPairsW (GDI32.@)
1855 DWORD WINAPI
GetKerningPairsW( HDC hDC
, DWORD cPairs
,
1856 LPKERNINGPAIR lpKerningPairs
)
1858 return GetKerningPairsA( hDC
, cPairs
, lpKerningPairs
);
1861 /*************************************************************************
1862 * TranslateCharsetInfo [GDI32.@]
1863 * TranslateCharsetInfo [USER32.@]
1865 * Fills a CHARSETINFO structure for a character set, code page, or
1866 * font. This allows making the correspondance between different labelings
1867 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1868 * of the same encoding.
1870 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1871 * only one codepage should be set in *lpSrc.
1874 * TRUE on success, FALSE on failure.
1877 BOOL WINAPI
TranslateCharsetInfo(
1878 LPDWORD lpSrc
, /* [in]
1879 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1880 if flags == TCI_SRCCHARSET: a character set value
1881 if flags == TCI_SRCCODEPAGE: a code page value
1883 LPCHARSETINFO lpCs
, /* [out] structure to receive charset information */
1884 DWORD flags
/* [in] determines interpretation of lpSrc */
1888 case TCI_SRCFONTSIG
:
1889 while (!(*lpSrc
>>index
& 0x0001) && index
<MAXTCIINDEX
) index
++;
1891 case TCI_SRCCODEPAGE
:
1892 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciACP
&& index
< MAXTCIINDEX
) index
++;
1894 case TCI_SRCCHARSET
:
1895 while ((UINT
) (lpSrc
) != FONT_tci
[index
].ciCharset
&& index
< MAXTCIINDEX
) index
++;
1900 if (index
>= MAXTCIINDEX
|| FONT_tci
[index
].ciCharset
== DEFAULT_CHARSET
) return FALSE
;
1901 memcpy(lpCs
, &FONT_tci
[index
], sizeof(CHARSETINFO
));
1905 /*************************************************************************
1906 * GetFontLanguageInfo (GDI32.@)
1908 DWORD WINAPI
GetFontLanguageInfo(HDC hdc
)
1910 FONTSIGNATURE fontsig
;
1911 static const DWORD GCP_DBCS_MASK
=0x003F0000,
1912 GCP_DIACRITIC_MASK
=0x00000000,
1913 FLI_GLYPHS_MASK
=0x00000000,
1914 GCP_GLYPHSHAPE_MASK
=0x00000040,
1915 GCP_KASHIDA_MASK
=0x00000000,
1916 GCP_LIGATE_MASK
=0x00000000,
1917 GCP_USEKERNING_MASK
=0x00000000,
1918 GCP_REORDER_MASK
=0x00000060;
1922 GetTextCharsetInfo( hdc
, &fontsig
, 0 );
1923 /* We detect each flag we return using a bitmask on the Codepage Bitfields */
1925 if( (fontsig
.fsCsb
[0]&GCP_DBCS_MASK
)!=0 )
1928 if( (fontsig
.fsCsb
[0]&GCP_DIACRITIC_MASK
)!=0 )
1929 result
|=GCP_DIACRITIC
;
1931 if( (fontsig
.fsCsb
[0]&FLI_GLYPHS_MASK
)!=0 )
1934 if( (fontsig
.fsCsb
[0]&GCP_GLYPHSHAPE_MASK
)!=0 )
1935 result
|=GCP_GLYPHSHAPE
;
1937 if( (fontsig
.fsCsb
[0]&GCP_KASHIDA_MASK
)!=0 )
1938 result
|=GCP_KASHIDA
;
1940 if( (fontsig
.fsCsb
[0]&GCP_LIGATE_MASK
)!=0 )
1943 if( (fontsig
.fsCsb
[0]&GCP_USEKERNING_MASK
)!=0 )
1944 result
|=GCP_USEKERNING
;
1946 if( (fontsig
.fsCsb
[0]&GCP_REORDER_MASK
)!=0 )
1947 result
|=GCP_REORDER
;
1953 /*************************************************************************
1954 * GetFontData [GDI32.@] Retrieve data for TrueType font
1958 * success: Number of bytes returned
1959 * failure: GDI_ERROR
1963 * Calls SetLastError()
1966 DWORD WINAPI
GetFontData(HDC hdc
, DWORD table
, DWORD offset
,
1967 LPVOID buffer
, DWORD length
)
1969 DC
*dc
= DC_GetDCPtr(hdc
);
1970 DWORD ret
= GDI_ERROR
;
1972 if(!dc
) return GDI_ERROR
;
1975 ret
= WineEngGetFontData(dc
->gdiFont
, table
, offset
, buffer
, length
);
1977 GDI_ReleaseObj(hdc
);
1981 /*************************************************************************
1982 * GetGlyphIndicesA [GDI32.@]
1984 DWORD WINAPI
GetGlyphIndicesA(HDC hdc
, LPCSTR lpstr
, INT count
,
1985 LPWORD pgi
, DWORD flags
)
1991 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
1992 hdc
, debugstr_an(lpstr
, count
), count
, pgi
, flags
);
1994 lpstrW
= FONT_mbtowc(hdc
, lpstr
, count
, &countW
, NULL
);
1995 ret
= GetGlyphIndicesW(hdc
, lpstrW
, countW
, pgi
, flags
);
1996 HeapFree(GetProcessHeap(), 0, lpstrW
);
2001 /*************************************************************************
2002 * GetGlyphIndicesW [GDI32.@]
2004 DWORD WINAPI
GetGlyphIndicesW(HDC hdc
, LPCWSTR lpstr
, INT count
,
2005 LPWORD pgi
, DWORD flags
)
2007 DC
*dc
= DC_GetDCPtr(hdc
);
2008 DWORD ret
= GDI_ERROR
;
2010 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2011 hdc
, debugstr_wn(lpstr
, count
), count
, pgi
, flags
);
2013 if(!dc
) return GDI_ERROR
;
2016 ret
= WineEngGetGlyphIndices(dc
->gdiFont
, lpstr
, count
, pgi
, flags
);
2018 GDI_ReleaseObj(hdc
);
2022 /*************************************************************************
2023 * GetCharacterPlacementA [GDI32.@]
2026 * the web browser control of ie4 calls this with dwFlags=0
2029 GetCharacterPlacementA(HDC hdc
, LPCSTR lpString
, INT uCount
,
2030 INT nMaxExtent
, GCP_RESULTSA
*lpResults
,
2035 GCP_RESULTSW resultsW
;
2039 TRACE("%s, %d, %d, 0x%08lx\n",
2040 debugstr_an(lpString
, uCount
), uCount
, nMaxExtent
, dwFlags
);
2042 /* both structs are equal in size */
2043 memcpy(&resultsW
, lpResults
, sizeof(resultsW
));
2045 lpStringW
= FONT_mbtowc(hdc
, lpString
, uCount
, &uCountW
, &font_cp
);
2046 if( dwFlags
&GCP_REORDER
)
2048 /* If the REORDER flag is not set, this field is ignored anyways */
2049 if(lpResults
->lpOutString
)
2050 resultsW
.lpOutString
= HeapAlloc(GetProcessHeap(), 0, uCountW
);
2052 resultsW
.lpOutString
= NULL
;
2055 ret
= GetCharacterPlacementW(hdc
, lpStringW
, uCountW
, nMaxExtent
, &resultsW
, dwFlags
);
2057 if(lpResults
->lpOutString
) {
2058 if(font_cp
!= CP_SYMBOL
)
2059 WideCharToMultiByte(font_cp
, 0, resultsW
.lpOutString
, uCountW
,
2060 lpResults
->lpOutString
, uCount
, NULL
, NULL
);
2062 for(i
= 0; i
< uCount
; i
++)
2063 lpResults
->lpOutString
[i
] = (CHAR
)resultsW
.lpOutString
[i
];
2066 HeapFree(GetProcessHeap(), 0, lpStringW
);
2067 HeapFree(GetProcessHeap(), 0, resultsW
.lpOutString
);
2072 /*************************************************************************
2073 * GetCharacterPlacementW [GDI32.@]
2075 * Retrieve information about a string. This includes the width, reordering,
2076 * Glyphing and so on.
2080 * The width and height of the string if succesful, 0 if failed.
2084 * All flags except GCP_REORDER are not yet implemented.
2085 * Reordering is not 100% complient to the Windows BiDi method.
2086 * Caret positioning is not yet implemented.
2087 * Classes are not yet implemented.
2091 GetCharacterPlacementW(
2092 HDC hdc
, /* [in] Device context for which the rendering is to be done */
2093 LPCWSTR lpString
, /* [in] The string for which information is to be returned */
2094 INT uCount
, /* [in] Number of WORDS in string. */
2095 INT nMaxExtent
, /* [in] Maximum extent the string is to take (in HDC logical units) */
2096 GCP_RESULTSW
*lpResults
,/* [in/out] A pointer to a GCP_RESULTSW struct */
2097 DWORD dwFlags
/* [in] Flags specifying how to process the string */
2104 TRACE("%s, %d, %d, 0x%08lx\n",
2105 debugstr_wn(lpString
, uCount
), uCount
, nMaxExtent
, dwFlags
);
2107 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2108 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2109 lpResults
->lStructSize
, lpResults
->lpOutString
, lpResults
->lpOrder
,
2110 lpResults
->lpDx
, lpResults
->lpCaretPos
, lpResults
->lpClass
,
2111 lpResults
->lpGlyphs
, lpResults
->nGlyphs
, lpResults
->nMaxFit
);
2113 if(dwFlags
&(~GCP_REORDER
)) FIXME("flags 0x%08lx ignored\n", dwFlags
);
2114 if(lpResults
->lpCaretPos
) FIXME("caret positions not implemented\n");
2115 if(lpResults
->lpClass
) FIXME("classes not implemented\n");
2117 nSet
= (UINT
)uCount
;
2118 if(nSet
> lpResults
->nGlyphs
)
2119 nSet
= lpResults
->nGlyphs
;
2121 /* return number of initialized fields */
2122 lpResults
->nGlyphs
= nSet
;
2124 if((dwFlags
&GCP_REORDER
)!=0)
2126 /* MSDN says lpOutString and lpOrder are ignored if GCP_REORDER not set */
2129 /* Keep a static table that translates the C2 types to something meaningful */
2130 /* 1 - left to right
2131 * -1 - right to left
2134 static const int chardir
[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
2136 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
2137 if( (pwCharType
=HeapAlloc(GetProcessHeap(), 0, uCount
* sizeof(WORD
)))==NULL
)
2139 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2144 /* Fill in the order array with directionality values */
2145 GetStringTypeW(CT_CTYPE2
, lpString
, uCount
, pwCharType
);
2147 /* The complete and correct (at least according to MS) BiDi algorythm is not
2148 * yet implemented here. Instead, we just make sure that consecutive runs of
2149 * the same direction (or neutral) are ordered correctly
2151 for( i
=0; i
<uCount
; i
+=run_end
)
2153 for( run_end
=1; i
+run_end
<uCount
&&
2154 (chardir
[pwCharType
[i
+run_end
]]==chardir
[pwCharType
[i
]] ||
2155 chardir
[pwCharType
[i
+run_end
]]==0); ++run_end
)
2158 if( chardir
[pwCharType
[i
]]==1 || chardir
[pwCharType
[i
]]==0 )
2161 if(lpResults
->lpOutString
)
2164 for( j
=0; j
<run_end
; j
++ )
2166 lpResults
->lpOutString
[i
+j
]=lpString
[i
+j
];
2170 if(lpResults
->lpOrder
)
2173 for( j
=0; j
<run_end
; j
++ )
2174 lpResults
->lpOrder
[i
+j
] = i
+j
;
2179 if(lpResults
->lpOutString
)
2182 for( j
=0; j
<run_end
; j
++ )
2184 lpResults
->lpOutString
[i
+j
]=lpString
[i
+run_end
-j
-1];
2188 if(lpResults
->lpOrder
)
2191 for( j
=0; j
<run_end
; j
++ )
2192 lpResults
->lpOrder
[i
+j
] = i
+run_end
-j
-1;
2197 HeapFree(GetProcessHeap(), 0, pwCharType
);
2200 /* FIXME: Will use the placement chars */
2201 if (lpResults
->lpDx
)
2204 for (i
= 0; i
< nSet
; i
++)
2206 if (GetCharWidth32W(hdc
, lpString
[i
], lpString
[i
], &c
))
2207 lpResults
->lpDx
[i
]= c
;
2211 if(lpResults
->lpGlyphs
)
2212 GetGlyphIndicesW(hdc
, lpString
, nSet
, lpResults
->lpGlyphs
, 0);
2214 if (GetTextExtentPoint32W(hdc
, lpString
, uCount
, &size
))
2215 ret
= MAKELONG(size
.cx
, size
.cy
);
2220 /*************************************************************************
2221 * GetCharABCWidthsFloatA [GDI32.@]
2223 BOOL WINAPI
GetCharABCWidthsFloatA(HDC hdc
, UINT iFirstChar
, UINT iLastChar
,
2226 FIXME_(gdi
)("GetCharABCWidthsFloatA, stub\n");
2230 /*************************************************************************
2231 * GetCharABCWidthsFloatW [GDI32.@]
2233 BOOL WINAPI
GetCharABCWidthsFloatW(HDC hdc
, UINT iFirstChar
,
2234 UINT iLastChar
, LPABCFLOAT lpABCF
)
2236 FIXME_(gdi
)("GetCharABCWidthsFloatW, stub\n");
2240 /*************************************************************************
2241 * GetCharWidthFloatA [GDI32.@]
2243 BOOL WINAPI
GetCharWidthFloatA(HDC hdc
, UINT iFirstChar
,
2244 UINT iLastChar
, PFLOAT pxBuffer
)
2246 FIXME_(gdi
)("GetCharWidthFloatA, stub\n");
2250 /*************************************************************************
2251 * GetCharWidthFloatW [GDI32.@]
2253 BOOL WINAPI
GetCharWidthFloatW(HDC hdc
, UINT iFirstChar
,
2254 UINT iLastChar
, PFLOAT pxBuffer
)
2256 FIXME_(gdi
)("GetCharWidthFloatW, stub\n");
2261 /***********************************************************************
2263 * Font Resource API *
2265 ***********************************************************************/
2267 /***********************************************************************
2268 * AddFontResourceA (GDI32.@)
2270 INT WINAPI
AddFontResourceA( LPCSTR str
)
2272 return AddFontResourceExA( str
, 0, NULL
);
2275 /***********************************************************************
2276 * AddFontResourceW (GDI32.@)
2278 INT WINAPI
AddFontResourceW( LPCWSTR str
)
2280 return AddFontResourceExW(str
, 0, NULL
);
2284 /***********************************************************************
2285 * AddFontResourceExA (GDI32.@)
2287 INT WINAPI
AddFontResourceExA( LPCSTR str
, DWORD fl
, PVOID pdv
)
2289 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
2290 LPWSTR strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2293 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2294 ret
= AddFontResourceExW(strW
, fl
, pdv
);
2295 HeapFree(GetProcessHeap(), 0, strW
);
2299 /***********************************************************************
2300 * AddFontResourceExW (GDI32.@)
2302 INT WINAPI
AddFontResourceExW( LPCWSTR str
, DWORD fl
, PVOID pdv
)
2304 return WineEngAddFontResourceEx(str
, fl
, pdv
);
2307 /***********************************************************************
2308 * RemoveFontResourceA (GDI32.@)
2310 BOOL WINAPI
RemoveFontResourceA( LPCSTR str
)
2312 return RemoveFontResourceExA(str
, 0, 0);
2315 /***********************************************************************
2316 * RemoveFontResourceW (GDI32.@)
2318 BOOL WINAPI
RemoveFontResourceW( LPCWSTR str
)
2320 return RemoveFontResourceExW(str
, 0, 0);
2323 /***********************************************************************
2324 * RemoveFontResourceExA (GDI32.@)
2326 BOOL WINAPI
RemoveFontResourceExA( LPCSTR str
, DWORD fl
, PVOID pdv
)
2328 DWORD len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
2329 LPWSTR strW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
2332 MultiByteToWideChar(CP_ACP
, 0, str
, -1, strW
, len
);
2333 ret
= RemoveFontResourceExW(strW
, fl
, pdv
);
2334 HeapFree(GetProcessHeap(), 0, strW
);
2338 /***********************************************************************
2339 * RemoveFontResourceExW (GDI32.@)
2341 BOOL WINAPI
RemoveFontResourceExW( LPCWSTR str
, DWORD fl
, PVOID pdv
)
2343 return WineEngRemoveFontResourceEx(str
, fl
, pdv
);