Added some more tests.
[wine.git] / objects / font.c
blob17ecc9fcce13f831ccc7dc3ec273eefc6a01628f
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
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
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 #include "winerror.h"
26 #include "winnls.h"
27 #include "wine/unicode.h"
28 #include "font.h"
29 #include "options.h"
30 #include "wine/debug.h"
31 #include "gdi.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(font);
34 WINE_DECLARE_DEBUG_CHANNEL(gdi);
36 #define ENUM_UNICODE 0x00000001
37 #define ENUM_CALLED 0x00000002
39 typedef struct
41 LPLOGFONT16 lpLogFontParam;
42 FONTENUMPROCEX16 lpEnumFunc;
43 LPARAM lpData;
45 LPNEWTEXTMETRICEX16 lpTextMetric;
46 LPENUMLOGFONTEX16 lpLogFont;
47 SEGPTR segTextMetric;
48 SEGPTR segLogFont;
49 HDC hdc;
50 DC *dc;
51 PHYSDEV physDev;
52 } fontEnum16;
54 typedef struct
56 LPLOGFONTW lpLogFontParam;
57 FONTENUMPROCEXW lpEnumFunc;
58 LPARAM lpData;
59 DWORD dwFlags;
60 HDC hdc;
61 DC *dc;
62 PHYSDEV physDev;
63 } fontEnum32;
66 * For TranslateCharsetInfo
68 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
69 #define MAXTCIINDEX 32
70 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
71 /* ANSI */
72 { ANSI_CHARSET, 1252, FS(0)},
73 { EASTEUROPE_CHARSET, 1250, FS(1)},
74 { RUSSIAN_CHARSET, 1251, FS(2)},
75 { GREEK_CHARSET, 1253, FS(3)},
76 { TURKISH_CHARSET, 1254, FS(4)},
77 { HEBREW_CHARSET, 1255, FS(5)},
78 { ARABIC_CHARSET, 1256, FS(6)},
79 { BALTIC_CHARSET, 1257, FS(7)},
80 /* reserved by ANSI */
81 { DEFAULT_CHARSET, 0, FS(0)},
82 { DEFAULT_CHARSET, 0, FS(0)},
83 { DEFAULT_CHARSET, 0, FS(0)},
84 { DEFAULT_CHARSET, 0, FS(0)},
85 { DEFAULT_CHARSET, 0, FS(0)},
86 { DEFAULT_CHARSET, 0, FS(0)},
87 { DEFAULT_CHARSET, 0, FS(0)},
88 { DEFAULT_CHARSET, 0, FS(0)},
89 /* ANSI and OEM */
90 { THAI_CHARSET, 874, FS(16)},
91 { SHIFTJIS_CHARSET, 932, FS(17)},
92 { GB2312_CHARSET, 936, FS(18)},
93 { HANGEUL_CHARSET, 949, FS(19)},
94 { CHINESEBIG5_CHARSET, 950, FS(20)},
95 { JOHAB_CHARSET, 1361, FS(21)},
96 /* reserved for alternate ANSI and OEM */
97 { DEFAULT_CHARSET, 0, FS(0)},
98 { DEFAULT_CHARSET, 0, FS(0)},
99 { DEFAULT_CHARSET, 0, FS(0)},
100 { DEFAULT_CHARSET, 0, FS(0)},
101 { DEFAULT_CHARSET, 0, FS(0)},
102 { DEFAULT_CHARSET, 0, FS(0)},
103 { DEFAULT_CHARSET, 0, FS(0)},
104 { DEFAULT_CHARSET, 0, FS(0)},
105 /* reserved for system */
106 { DEFAULT_CHARSET, 0, FS(0)},
107 { DEFAULT_CHARSET, 0, FS(0)},
110 /* ### start build ### */
111 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
112 /* ### stop build ### */
114 /***********************************************************************
115 * LOGFONT conversion functions.
117 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
119 font16->lfHeight = font32->lfHeight;
120 font16->lfWidth = font32->lfWidth;
121 font16->lfEscapement = font32->lfEscapement;
122 font16->lfOrientation = font32->lfOrientation;
123 font16->lfWeight = font32->lfWeight;
124 font16->lfItalic = font32->lfItalic;
125 font16->lfUnderline = font32->lfUnderline;
126 font16->lfStrikeOut = font32->lfStrikeOut;
127 font16->lfCharSet = font32->lfCharSet;
128 font16->lfOutPrecision = font32->lfOutPrecision;
129 font16->lfClipPrecision = font32->lfClipPrecision;
130 font16->lfQuality = font32->lfQuality;
131 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
132 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
135 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
137 font16->lfHeight = font32->lfHeight;
138 font16->lfWidth = font32->lfWidth;
139 font16->lfEscapement = font32->lfEscapement;
140 font16->lfOrientation = font32->lfOrientation;
141 font16->lfWeight = font32->lfWeight;
142 font16->lfItalic = font32->lfItalic;
143 font16->lfUnderline = font32->lfUnderline;
144 font16->lfStrikeOut = font32->lfStrikeOut;
145 font16->lfCharSet = font32->lfCharSet;
146 font16->lfOutPrecision = font32->lfOutPrecision;
147 font16->lfClipPrecision = font32->lfClipPrecision;
148 font16->lfQuality = font32->lfQuality;
149 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
150 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
151 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
152 font16->lfFaceName[LF_FACESIZE-1] = 0;
155 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
157 font32->lfHeight = font16->lfHeight;
158 font32->lfWidth = font16->lfWidth;
159 font32->lfEscapement = font16->lfEscapement;
160 font32->lfOrientation = font16->lfOrientation;
161 font32->lfWeight = font16->lfWeight;
162 font32->lfItalic = font16->lfItalic;
163 font32->lfUnderline = font16->lfUnderline;
164 font32->lfStrikeOut = font16->lfStrikeOut;
165 font32->lfCharSet = font16->lfCharSet;
166 font32->lfOutPrecision = font16->lfOutPrecision;
167 font32->lfClipPrecision = font16->lfClipPrecision;
168 font32->lfQuality = font16->lfQuality;
169 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
170 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
173 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
175 font32->lfHeight = font16->lfHeight;
176 font32->lfWidth = font16->lfWidth;
177 font32->lfEscapement = font16->lfEscapement;
178 font32->lfOrientation = font16->lfOrientation;
179 font32->lfWeight = font16->lfWeight;
180 font32->lfItalic = font16->lfItalic;
181 font32->lfUnderline = font16->lfUnderline;
182 font32->lfStrikeOut = font16->lfStrikeOut;
183 font32->lfCharSet = font16->lfCharSet;
184 font32->lfOutPrecision = font16->lfOutPrecision;
185 font32->lfClipPrecision = font16->lfClipPrecision;
186 font32->lfQuality = font16->lfQuality;
187 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
188 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
189 font32->lfFaceName[LF_FACESIZE-1] = 0;
192 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
194 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
195 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
196 LF_FACESIZE);
199 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
201 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
202 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
203 LF_FACESIZE, NULL, NULL);
206 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
208 FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
209 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
210 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
211 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
214 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
216 FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
218 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
219 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
220 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
221 font32->elfStyle[LF_FACESIZE-1] = 0;
222 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
223 font32->elfScript[LF_FACESIZE-1] = 0;
226 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
228 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
230 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
231 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
232 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
233 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
234 font16->elfStyle, LF_FACESIZE, NULL, NULL );
235 font16->elfStyle[LF_FACESIZE-1] = '\0';
236 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
237 font16->elfScript, LF_FACESIZE, NULL, NULL );
238 font16->elfScript[LF_FACESIZE-1] = '\0';
241 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
243 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
245 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
246 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
247 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
248 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
249 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
250 fontA->elfStyle[LF_FACESIZE-1] = '\0';
251 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
252 fontA->elfScript, LF_FACESIZE, NULL, NULL );
253 fontA->elfScript[LF_FACESIZE-1] = '\0';
256 /***********************************************************************
257 * TEXTMETRIC conversion functions.
259 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
261 ptm16->tmHeight = ptm32->tmHeight;
262 ptm16->tmAscent = ptm32->tmAscent;
263 ptm16->tmDescent = ptm32->tmDescent;
264 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
265 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
266 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
267 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
268 ptm16->tmWeight = ptm32->tmWeight;
269 ptm16->tmOverhang = ptm32->tmOverhang;
270 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
271 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
272 ptm16->tmFirstChar = ptm32->tmFirstChar;
273 ptm16->tmLastChar = ptm32->tmLastChar;
274 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
275 ptm16->tmBreakChar = ptm32->tmBreakChar;
276 ptm16->tmItalic = ptm32->tmItalic;
277 ptm16->tmUnderlined = ptm32->tmUnderlined;
278 ptm16->tmStruckOut = ptm32->tmStruckOut;
279 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
280 ptm16->tmCharSet = ptm32->tmCharSet;
283 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
285 ptm16->tmHeight = ptm32->tmHeight;
286 ptm16->tmAscent = ptm32->tmAscent;
287 ptm16->tmDescent = ptm32->tmDescent;
288 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
289 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
290 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
291 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
292 ptm16->tmWeight = ptm32->tmWeight;
293 ptm16->tmOverhang = ptm32->tmOverhang;
294 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
295 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
296 ptm16->tmFirstChar = ptm32->tmFirstChar;
297 ptm16->tmLastChar = ptm32->tmLastChar;
298 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
299 ptm16->tmBreakChar = ptm32->tmBreakChar;
300 ptm16->tmItalic = ptm32->tmItalic;
301 ptm16->tmUnderlined = ptm32->tmUnderlined;
302 ptm16->tmStruckOut = ptm32->tmStruckOut;
303 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
304 ptm16->tmCharSet = ptm32->tmCharSet;
307 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
309 ptm32->tmHeight = ptm16->tmHeight;
310 ptm32->tmAscent = ptm16->tmAscent;
311 ptm32->tmDescent = ptm16->tmDescent;
312 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
313 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
314 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
315 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
316 ptm32->tmWeight = ptm16->tmWeight;
317 ptm32->tmOverhang = ptm16->tmOverhang;
318 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
319 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
320 ptm32->tmFirstChar = ptm16->tmFirstChar;
321 ptm32->tmLastChar = ptm16->tmLastChar;
322 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
323 ptm32->tmBreakChar = ptm16->tmBreakChar;
324 ptm32->tmItalic = ptm16->tmItalic;
325 ptm32->tmUnderlined = ptm16->tmUnderlined;
326 ptm32->tmStruckOut = ptm16->tmStruckOut;
327 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
328 ptm32->tmCharSet = ptm16->tmCharSet;
331 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
333 ptm32->tmHeight = ptm16->tmHeight;
334 ptm32->tmAscent = ptm16->tmAscent;
335 ptm32->tmDescent = ptm16->tmDescent;
336 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
337 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
338 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
339 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
340 ptm32->tmWeight = ptm16->tmWeight;
341 ptm32->tmOverhang = ptm16->tmOverhang;
342 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
343 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
344 ptm32->tmFirstChar = ptm16->tmFirstChar;
345 ptm32->tmLastChar = ptm16->tmLastChar;
346 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
347 ptm32->tmBreakChar = ptm16->tmBreakChar;
348 ptm32->tmItalic = ptm16->tmItalic;
349 ptm32->tmUnderlined = ptm16->tmUnderlined;
350 ptm32->tmStruckOut = ptm16->tmStruckOut;
351 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
352 ptm32->tmCharSet = ptm16->tmCharSet;
355 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
357 ptm32W->tmHeight = ptm32A->tmHeight;
358 ptm32W->tmAscent = ptm32A->tmAscent;
359 ptm32W->tmDescent = ptm32A->tmDescent;
360 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
361 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
362 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
363 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
364 ptm32W->tmWeight = ptm32A->tmWeight;
365 ptm32W->tmOverhang = ptm32A->tmOverhang;
366 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
367 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
368 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
369 ptm32W->tmLastChar = ptm32A->tmLastChar;
370 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
371 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
372 ptm32W->tmItalic = ptm32A->tmItalic;
373 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
374 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
375 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
376 ptm32W->tmCharSet = ptm32A->tmCharSet;
379 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
381 ptmA->tmHeight = ptmW->tmHeight;
382 ptmA->tmAscent = ptmW->tmAscent;
383 ptmA->tmDescent = ptmW->tmDescent;
384 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
385 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
386 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
387 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
388 ptmA->tmWeight = ptmW->tmWeight;
389 ptmA->tmOverhang = ptmW->tmOverhang;
390 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
391 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
392 ptmA->tmFirstChar = ptmW->tmFirstChar;
393 ptmA->tmLastChar = ptmW->tmLastChar;
394 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
395 ptmA->tmBreakChar = ptmW->tmBreakChar;
396 ptmA->tmItalic = ptmW->tmItalic;
397 ptmA->tmUnderlined = ptmW->tmUnderlined;
398 ptmA->tmStruckOut = ptmW->tmStruckOut;
399 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
400 ptmA->tmCharSet = ptmW->tmCharSet;
404 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
406 FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
407 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
408 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
409 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
410 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
411 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
414 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
416 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
417 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
418 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
419 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
420 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
421 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
424 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
426 FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
427 ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
428 ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
429 ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
430 ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
431 memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
435 /***********************************************************************
436 * CreateFontIndirect (GDI.57)
438 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
440 LOGFONTW lfW;
442 if(plf16) {
443 FONT_LogFont16ToW( plf16, &lfW );
444 return CreateFontIndirectW( &lfW );
445 } else {
446 return CreateFontIndirectW( NULL );
451 /***********************************************************************
452 * CreateFontIndirectA (GDI32.@)
454 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
456 LOGFONTW lfW;
458 if (plfA) {
459 FONT_LogFontAToW( plfA, &lfW );
460 return CreateFontIndirectW( &lfW );
461 } else
462 return CreateFontIndirectW( NULL );
466 /***********************************************************************
467 * CreateFontIndirectW (GDI32.@)
469 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
471 HFONT hFont = 0;
473 if (plf)
475 FONTOBJ* fontPtr;
476 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
478 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
480 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
481 plf->lfHeight, plf->lfWidth,
482 plf->lfEscapement, plf->lfOrientation,
483 plf->lfPitchAndFamily,
484 debugstr_w(plf->lfFaceName),
485 plf->lfWeight > 400 ? "Bold" : "",
486 plf->lfItalic ? "Italic" : "", hFont);
488 if (plf->lfEscapement != plf->lfOrientation) {
489 /* this should really depend on whether GM_ADVANCED is set */
490 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
491 WARN("orientation angle %f set to "
492 "escapement angle %f for new font %04x\n",
493 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
495 GDI_ReleaseObj( hFont );
498 else WARN("(NULL) => NULL\n");
500 return hFont;
503 /***********************************************************************
504 * CreateFont (GDI.56)
506 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
507 INT16 weight, BYTE italic, BYTE underline,
508 BYTE strikeout, BYTE charset, BYTE outpres,
509 BYTE clippres, BYTE quality, BYTE pitch,
510 LPCSTR name )
512 LOGFONT16 logfont;
514 logfont.lfHeight = height;
515 logfont.lfWidth = width;
516 logfont.lfEscapement = esc;
517 logfont.lfOrientation = orient;
518 logfont.lfWeight = weight;
519 logfont.lfItalic = italic;
520 logfont.lfUnderline = underline;
521 logfont.lfStrikeOut = strikeout;
522 logfont.lfCharSet = charset;
523 logfont.lfOutPrecision = outpres;
524 logfont.lfClipPrecision = clippres;
525 logfont.lfQuality = quality;
526 logfont.lfPitchAndFamily = pitch;
528 if (name)
529 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
530 else
531 logfont.lfFaceName[0] = '\0';
533 return CreateFontIndirect16( &logfont );
536 /*************************************************************************
537 * CreateFontA (GDI32.@)
539 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
540 INT orient, INT weight, DWORD italic,
541 DWORD underline, DWORD strikeout, DWORD charset,
542 DWORD outpres, DWORD clippres, DWORD quality,
543 DWORD pitch, LPCSTR name )
545 LOGFONTA logfont;
547 logfont.lfHeight = height;
548 logfont.lfWidth = width;
549 logfont.lfEscapement = esc;
550 logfont.lfOrientation = orient;
551 logfont.lfWeight = weight;
552 logfont.lfItalic = italic;
553 logfont.lfUnderline = underline;
554 logfont.lfStrikeOut = strikeout;
555 logfont.lfCharSet = charset;
556 logfont.lfOutPrecision = outpres;
557 logfont.lfClipPrecision = clippres;
558 logfont.lfQuality = quality;
559 logfont.lfPitchAndFamily = pitch;
561 if (name)
562 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
563 else
564 logfont.lfFaceName[0] = '\0';
566 return CreateFontIndirectA( &logfont );
569 /*************************************************************************
570 * CreateFontW (GDI32.@)
572 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
573 INT orient, INT weight, DWORD italic,
574 DWORD underline, DWORD strikeout, DWORD charset,
575 DWORD outpres, DWORD clippres, DWORD quality,
576 DWORD pitch, LPCWSTR name )
578 LOGFONTW logfont;
580 logfont.lfHeight = height;
581 logfont.lfWidth = width;
582 logfont.lfEscapement = esc;
583 logfont.lfOrientation = orient;
584 logfont.lfWeight = weight;
585 logfont.lfItalic = italic;
586 logfont.lfUnderline = underline;
587 logfont.lfStrikeOut = strikeout;
588 logfont.lfCharSet = charset;
589 logfont.lfOutPrecision = outpres;
590 logfont.lfClipPrecision = clippres;
591 logfont.lfQuality = quality;
592 logfont.lfPitchAndFamily = pitch;
594 if (name)
595 lstrcpynW(logfont.lfFaceName, name,
596 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
597 else
598 logfont.lfFaceName[0] = '\0';
600 return CreateFontIndirectW( &logfont );
604 /***********************************************************************
605 * FONT_GetObject16
607 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
609 LOGFONT16 lf16;
611 FONT_LogFontWTo16( &font->logfont, &lf16 );
613 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
614 memcpy( buffer, &lf16, count );
615 return count;
618 /***********************************************************************
619 * FONT_GetObjectA
621 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
623 LOGFONTA lfA;
625 FONT_LogFontWToA( &font->logfont, &lfA );
627 if (count > sizeof(lfA)) count = sizeof(lfA);
628 memcpy( buffer, &lfA, count );
629 return count;
631 /***********************************************************************
632 * FONT_GetObjectW
634 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
636 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
637 memcpy( buffer, &font->logfont, count );
638 return count;
642 /***********************************************************************
643 * FONT_EnumInstance16
645 * Called by the device driver layer to pass font info
646 * down to the application.
648 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
649 DWORD fType, LPARAM lp )
651 fontEnum16 *pfe = (fontEnum16*)lp;
652 INT ret = 1;
653 DC *dc;
655 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
656 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
658 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
659 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
660 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
662 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
663 (UINT16)fType, (LPARAM)pfe->lpData );
664 /* get the lock again and make sure the DC is still valid */
665 dc = DC_GetDCPtr( pfe->hdc );
666 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
668 if (dc) GDI_ReleaseObj( pfe->hdc );
669 pfe->hdc = 0; /* make sure we don't try to release it later on */
670 ret = 0;
673 return ret;
676 /***********************************************************************
677 * FONT_EnumInstance
679 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
680 DWORD fType, LPARAM lp )
682 fontEnum32 *pfe = (fontEnum32*)lp;
683 INT ret = 1;
684 DC *dc;
686 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
687 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
688 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
690 /* convert font metrics */
691 ENUMLOGFONTEXA logfont;
692 NEWTEXTMETRICEXA tmA;
694 pfe->dwFlags |= ENUM_CALLED;
695 if (!(pfe->dwFlags & ENUM_UNICODE))
697 FONT_EnumLogFontExWToA( plf, &logfont);
698 FONT_NewTextMetricExWToA( ptm, &tmA );
699 plf = (LPENUMLOGFONTEXW)&logfont;
700 ptm = (LPNEWTEXTMETRICEXW)&tmA;
702 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
704 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
706 /* get the lock again and make sure the DC is still valid */
707 dc = DC_GetDCPtr( pfe->hdc );
708 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
710 if (dc) GDI_ReleaseObj( pfe->hdc );
711 pfe->hdc = 0; /* make sure we don't try to release it later on */
712 ret = 0;
715 return ret;
718 /***********************************************************************
719 * EnumFontFamiliesEx (GDI.613)
721 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
722 FONTENUMPROCEX16 efproc, LPARAM lParam,
723 DWORD dwFlags)
725 fontEnum16 fe16;
726 INT16 retVal = 0;
727 DC* dc = DC_GetDCPtr( hDC );
729 if (!dc) return 0;
730 fe16.hdc = hDC;
731 fe16.dc = dc;
732 fe16.physDev = dc->physDev;
734 if (dc->funcs->pEnumDeviceFonts)
736 NEWTEXTMETRICEX16 tm16;
737 ENUMLOGFONTEX16 lf16;
738 LOGFONTW lfW;
739 FONT_LogFont16ToW(plf, &lfW);
741 fe16.lpLogFontParam = plf;
742 fe16.lpEnumFunc = efproc;
743 fe16.lpData = lParam;
744 fe16.lpTextMetric = &tm16;
745 fe16.lpLogFont = &lf16;
746 fe16.segTextMetric = MapLS( &tm16 );
747 fe16.segLogFont = MapLS( &lf16 );
749 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
750 FONT_EnumInstance16, (LPARAM)&fe16 );
751 UnMapLS( fe16.segTextMetric );
752 UnMapLS( fe16.segLogFont );
754 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
755 return retVal;
758 /***********************************************************************
759 * FONT_EnumFontFamiliesEx
761 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
762 FONTENUMPROCEXW efproc,
763 LPARAM lParam, DWORD dwUnicode)
765 INT ret = 1, ret2;
766 DC *dc = DC_GetDCPtr( hDC );
767 fontEnum32 fe32;
768 BOOL enum_gdi_fonts;
770 if (!dc) return 0;
772 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
773 plf->lfCharSet);
774 fe32.lpLogFontParam = plf;
775 fe32.lpEnumFunc = efproc;
776 fe32.lpData = lParam;
777 fe32.dwFlags = dwUnicode;
778 fe32.hdc = hDC;
779 fe32.dc = dc;
780 fe32.physDev = dc->physDev;
782 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
784 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
786 ret = 0;
787 goto done;
790 if (enum_gdi_fonts)
791 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
792 fe32.dwFlags &= ~ENUM_CALLED;
793 if (ret && dc->funcs->pEnumDeviceFonts) {
794 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
795 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
796 ret = ret2;
798 done:
799 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
800 return ret;
803 /***********************************************************************
804 * EnumFontFamiliesExW (GDI32.@)
806 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
807 FONTENUMPROCEXW efproc,
808 LPARAM lParam, DWORD dwFlags )
810 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
813 /***********************************************************************
814 * EnumFontFamiliesExA (GDI32.@)
816 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
817 FONTENUMPROCEXA efproc,
818 LPARAM lParam, DWORD dwFlags)
820 LOGFONTW lfW;
821 FONT_LogFontAToW( plf, &lfW );
823 return FONT_EnumFontFamiliesEx( hDC, &lfW,
824 (FONTENUMPROCEXW)efproc, lParam, 0);
827 /***********************************************************************
828 * EnumFontFamilies (GDI.330)
830 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
831 FONTENUMPROC16 efproc, LPARAM lpData )
833 LOGFONT16 lf;
835 lf.lfCharSet = DEFAULT_CHARSET;
836 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
837 else lf.lfFaceName[0] = '\0';
839 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
842 /***********************************************************************
843 * EnumFontFamiliesA (GDI32.@)
845 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
846 FONTENUMPROCA efproc, LPARAM lpData )
848 LOGFONTA lf;
850 lf.lfCharSet = DEFAULT_CHARSET;
851 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
852 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
854 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
857 /***********************************************************************
858 * EnumFontFamiliesW (GDI32.@)
860 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
861 FONTENUMPROCW efproc, LPARAM lpData )
863 LOGFONTW lf;
865 lf.lfCharSet = DEFAULT_CHARSET;
866 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
867 else lf.lfFaceName[0] = 0;
869 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
872 /***********************************************************************
873 * EnumFonts (GDI.70)
875 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
876 LPARAM lpData )
878 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
881 /***********************************************************************
882 * EnumFontsA (GDI32.@)
884 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
885 LPARAM lpData )
887 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
890 /***********************************************************************
891 * EnumFontsW (GDI32.@)
893 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
894 LPARAM lpData )
896 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
900 /***********************************************************************
901 * GetTextCharacterExtra (GDI.89)
903 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
905 return (INT16)GetTextCharacterExtra( hdc );
909 /***********************************************************************
910 * GetTextCharacterExtra (GDI32.@)
912 INT WINAPI GetTextCharacterExtra( HDC hdc )
914 INT ret;
915 DC *dc = DC_GetDCPtr( hdc );
916 if (!dc) return 0;
917 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
918 / dc->vportExtX );
919 GDI_ReleaseObj( hdc );
920 return ret;
924 /***********************************************************************
925 * SetTextCharacterExtra (GDI.8)
927 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
929 return (INT16)SetTextCharacterExtra( hdc, extra );
933 /***********************************************************************
934 * SetTextCharacterExtra (GDI32.@)
936 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
938 INT prev;
939 DC * dc = DC_GetDCPtr( hdc );
940 if (!dc) return 0;
941 if (dc->funcs->pSetTextCharacterExtra)
942 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
943 else
945 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
946 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
947 dc->charExtra = abs(extra);
949 GDI_ReleaseObj( hdc );
950 return prev;
954 /***********************************************************************
955 * SetTextJustification (GDI.10)
957 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
959 return SetTextJustification( hdc, extra, breaks );
963 /***********************************************************************
964 * SetTextJustification (GDI32.@)
966 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
968 BOOL ret = TRUE;
969 DC * dc = DC_GetDCPtr( hdc );
970 if (!dc) return FALSE;
971 if (dc->funcs->pSetTextJustification)
972 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
973 else
975 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
976 if (!extra) breaks = 0;
977 dc->breakTotalExtra = extra;
978 dc->breakCount = breaks;
979 if (breaks)
981 dc->breakExtra = extra / breaks;
982 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
984 else
986 dc->breakExtra = 0;
987 dc->breakRem = 0;
990 GDI_ReleaseObj( hdc );
991 return ret;
995 /***********************************************************************
996 * GetTextFace (GDI.92)
998 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
1000 return GetTextFaceA(hdc,count,name);
1003 /***********************************************************************
1004 * GetTextFaceA (GDI32.@)
1006 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
1008 INT res = GetTextFaceW(hdc, 0, NULL);
1009 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
1010 GetTextFaceW( hdc, res, nameW );
1012 if (name)
1013 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
1014 NULL, NULL);
1015 else
1016 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
1017 HeapFree( GetProcessHeap(), 0, nameW );
1018 return res;
1021 /***********************************************************************
1022 * GetTextFaceW (GDI32.@)
1024 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
1026 FONTOBJ *font;
1027 INT ret = 0;
1029 DC * dc = DC_GetDCPtr( hdc );
1030 if (!dc) return 0;
1032 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1034 if (name)
1036 lstrcpynW( name, font->logfont.lfFaceName, count );
1037 ret = strlenW(name);
1039 else ret = strlenW(font->logfont.lfFaceName) + 1;
1040 GDI_ReleaseObj( dc->hFont );
1042 GDI_ReleaseObj( hdc );
1043 return ret;
1047 /***********************************************************************
1048 * GetTextExtent (GDI.91)
1050 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1052 SIZE16 size;
1053 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1054 return MAKELONG( size.cx, size.cy );
1058 /***********************************************************************
1059 * GetTextExtentPoint (GDI.471)
1061 * FIXME: Should this have a bug for compatibility?
1062 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1063 * bugs (-> MSDN KB q147647.txt).
1065 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1066 LPSIZE16 size )
1068 SIZE size32;
1069 BOOL ret;
1070 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1071 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1072 size->cx = size32.cx;
1073 size->cy = size32.cy;
1074 return (BOOL16)ret;
1078 /***********************************************************************
1079 * GetTextExtentPoint32A (GDI32.@)
1081 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1082 LPSIZE size )
1084 BOOL ret = FALSE;
1085 INT wlen;
1086 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1088 if (p) {
1089 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1090 HeapFree( GetProcessHeap(), 0, p );
1093 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1094 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1095 return ret;
1099 /***********************************************************************
1100 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1102 * Computes width and height of the specified string.
1104 * RETURNS
1105 * Success: TRUE
1106 * Failure: FALSE
1108 BOOL WINAPI GetTextExtentPoint32W(
1109 HDC hdc, /* [in] Handle of device context */
1110 LPCWSTR str, /* [in] Address of text string */
1111 INT count, /* [in] Number of characters in string */
1112 LPSIZE size) /* [out] Address of structure for string size */
1114 BOOL ret = FALSE;
1115 DC * dc = DC_GetDCPtr( hdc );
1116 if (!dc) return FALSE;
1118 if(dc->gdiFont) {
1119 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1120 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1121 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1123 else if(dc->funcs->pGetTextExtentPoint)
1124 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1126 GDI_ReleaseObj( hdc );
1128 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1129 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1130 return ret;
1133 /***********************************************************************
1134 * GetTextExtentPointI [GDI32.@]
1136 * Computes width and height of the array of glyph indices.
1138 * RETURNS
1139 * Success: TRUE
1140 * Failure: FALSE
1142 BOOL WINAPI GetTextExtentPointI(
1143 HDC hdc, /* [in] Handle of device context */
1144 const WORD *indices, /* [in] Address of glyph index array */
1145 INT count, /* [in] Number of glyphs in array */
1146 LPSIZE size) /* [out] Address of structure for string size */
1148 BOOL ret = FALSE;
1149 DC * dc = DC_GetDCPtr( hdc );
1150 if (!dc) return FALSE;
1152 if(dc->gdiFont) {
1153 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1154 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1155 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1157 else if(dc->funcs->pGetTextExtentPoint) {
1158 FIXME("calling GetTextExtentPoint\n");
1159 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1162 GDI_ReleaseObj( hdc );
1164 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1165 hdc, indices, count, size, size->cx, size->cy );
1166 return ret;
1170 /***********************************************************************
1171 * GetTextExtentPointA (GDI32.@)
1173 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1174 LPSIZE size )
1176 TRACE("not bug compatible.\n");
1177 return GetTextExtentPoint32A( hdc, str, count, size );
1180 /***********************************************************************
1181 * GetTextExtentPointW (GDI32.@)
1183 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1184 LPSIZE size )
1186 TRACE("not bug compatible.\n");
1187 return GetTextExtentPoint32W( hdc, str, count, size );
1191 /***********************************************************************
1192 * GetTextExtentExPointA (GDI32.@)
1194 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1195 INT maxExt, LPINT lpnFit,
1196 LPINT alpDx, LPSIZE size )
1198 BOOL ret;
1199 INT wlen;
1200 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1201 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1202 HeapFree( GetProcessHeap(), 0, p );
1203 return ret;
1207 /***********************************************************************
1208 * GetTextExtentExPointW (GDI32.@)
1210 * Return the size of the string as it would be if it was output properly by
1211 * e.g. TextOut.
1213 * This should include
1214 * - Intercharacter spacing
1215 * - justification spacing (not yet done)
1216 * - kerning? see below
1218 * Kerning. Since kerning would be carried out by the rendering code it should
1219 * be done by the driver. However they don't support it yet. Also I am not
1220 * yet persuaded that (certainly under Win95) any kerning is actually done.
1222 * str: According to MSDN this should be null-terminated. That is not true; a
1223 * null will not terminate it early.
1224 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1225 * than count. I have seen it be either the size of the full string or
1226 * 1 less than the size of the full string. I have not seen it bear any
1227 * resemblance to the portion that would fit.
1228 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1229 * trailing intercharacter spacing and any trailing justification.
1231 * FIXME
1232 * Currently we do this by measuring each character etc. We should do it by
1233 * passing the request to the driver, perhaps by extending the
1234 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1235 * thinking about kerning issues and rounding issues in the justification.
1238 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1239 INT maxExt, LPINT lpnFit,
1240 LPINT alpDx, LPSIZE size )
1242 int index, nFit, extent;
1243 SIZE tSize;
1244 BOOL ret = FALSE;
1246 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1248 size->cx = size->cy = nFit = extent = 0;
1249 for(index = 0; index < count; index++)
1251 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1252 /* GetTextExtentPoint includes intercharacter spacing. */
1253 /* FIXME - justification needs doing yet. Remember that the base
1254 * data will not be in logical coordinates.
1256 extent += tSize.cx;
1257 if( !lpnFit || extent <= maxExt )
1258 /* It is allowed to be equal. */
1260 nFit++;
1261 if( alpDx ) alpDx[index] = extent;
1263 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1264 str++;
1266 size->cx = extent;
1267 if(lpnFit) *lpnFit = nFit;
1268 ret = TRUE;
1270 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1272 done:
1273 return ret;
1276 /***********************************************************************
1277 * GetTextMetrics (GDI.93)
1279 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1281 TEXTMETRICW tm32;
1283 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1284 FONT_TextMetricWTo16( &tm32, metrics );
1285 return TRUE;
1289 /***********************************************************************
1290 * GetTextMetricsA (GDI32.@)
1292 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1294 TEXTMETRICW tm32;
1296 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1297 FONT_TextMetricWToA( &tm32, metrics );
1298 return TRUE;
1301 /***********************************************************************
1302 * GetTextMetricsW (GDI32.@)
1304 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1306 BOOL ret = FALSE;
1307 DC * dc = DC_GetDCPtr( hdc );
1308 if (!dc) return FALSE;
1310 if (dc->gdiFont)
1311 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1312 else if (dc->funcs->pGetTextMetrics)
1313 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1315 if (ret)
1317 /* device layer returns values in device units
1318 * therefore we have to convert them to logical */
1320 #define WDPTOLP(x) ((x<0)? \
1321 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1322 (abs((x)*dc->wndExtX/dc->vportExtX)))
1323 #define HDPTOLP(y) ((y<0)? \
1324 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1325 (abs((y)*dc->wndExtY/dc->vportExtY)))
1327 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1328 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1329 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1330 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1331 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1332 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1333 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1334 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1335 ret = TRUE;
1337 TRACE("text metrics:\n"
1338 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1339 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1340 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1341 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1342 " PitchAndFamily = %02x\n"
1343 " --------------------\n"
1344 " InternalLeading = %li\n"
1345 " Ascent = %li\n"
1346 " Descent = %li\n"
1347 " Height = %li\n",
1348 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1349 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1350 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1351 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1352 metrics->tmPitchAndFamily,
1353 metrics->tmInternalLeading,
1354 metrics->tmAscent,
1355 metrics->tmDescent,
1356 metrics->tmHeight );
1358 GDI_ReleaseObj( hdc );
1359 return ret;
1363 /***********************************************************************
1364 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1366 * NOTES
1367 * lpOTM should be LPOUTLINETEXTMETRIC
1369 * RETURNS
1370 * Success: Non-zero or size of required buffer
1371 * Failure: 0
1373 UINT16 WINAPI GetOutlineTextMetrics16(
1374 HDC16 hdc, /* [in] Handle of device context */
1375 UINT16 cbData, /* [in] Size of metric data array */
1376 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1378 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1379 return 0;
1383 /***********************************************************************
1384 * GetOutlineTextMetricsA (GDI32.@)
1385 * Gets metrics for TrueType fonts.
1388 * RETURNS
1389 * Success: Non-zero or size of required buffer
1390 * Failure: 0
1392 UINT WINAPI GetOutlineTextMetricsA(
1393 HDC hdc, /* [in] Handle of device context */
1394 UINT cbData, /* [in] Size of metric data array */
1395 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1397 char buf[512], *ptr;
1398 UINT ret, needed;
1399 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1400 INT left, len;
1402 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1403 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1404 return 0;
1405 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1406 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1409 needed = sizeof(OUTLINETEXTMETRICA);
1410 if(lpOTMW->otmpFamilyName)
1411 needed += WideCharToMultiByte(CP_ACP, 0,
1412 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1413 NULL, 0, NULL, NULL);
1414 if(lpOTMW->otmpFaceName)
1415 needed += WideCharToMultiByte(CP_ACP, 0,
1416 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1417 NULL, 0, NULL, NULL);
1418 if(lpOTMW->otmpStyleName)
1419 needed += WideCharToMultiByte(CP_ACP, 0,
1420 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1421 NULL, 0, NULL, NULL);
1422 if(lpOTMW->otmpFullName)
1423 needed += WideCharToMultiByte(CP_ACP, 0,
1424 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1425 NULL, 0, NULL, NULL);
1427 if(!lpOTM) {
1428 ret = needed;
1429 goto end;
1432 if(needed > cbData) {
1433 ret = 0;
1434 goto end;
1438 lpOTM->otmSize = needed;
1439 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1440 lpOTM->otmFiller = 0;
1441 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1442 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1443 lpOTM->otmfsType = lpOTMW->otmfsType;
1444 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1445 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1446 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1447 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1448 lpOTM->otmAscent = lpOTMW->otmAscent;
1449 lpOTM->otmDescent = lpOTMW->otmDescent;
1450 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1451 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1452 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1453 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1454 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1455 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1456 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1457 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1458 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1459 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1460 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1461 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1462 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1463 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1464 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1465 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1468 ptr = (char*)(lpOTM + 1);
1469 left = needed - sizeof(*lpOTM);
1471 if(lpOTMW->otmpFamilyName) {
1472 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1473 len = WideCharToMultiByte(CP_ACP, 0,
1474 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1475 ptr, left, NULL, NULL);
1476 left -= len;
1477 ptr += len;
1478 } else
1479 lpOTM->otmpFamilyName = 0;
1481 if(lpOTMW->otmpFaceName) {
1482 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1483 len = WideCharToMultiByte(CP_ACP, 0,
1484 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1485 ptr, left, NULL, NULL);
1486 left -= len;
1487 ptr += len;
1488 } else
1489 lpOTM->otmpFaceName = 0;
1491 if(lpOTMW->otmpStyleName) {
1492 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1493 len = WideCharToMultiByte(CP_ACP, 0,
1494 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1495 ptr, left, NULL, NULL);
1496 left -= len;
1497 ptr += len;
1498 } else
1499 lpOTM->otmpStyleName = 0;
1501 if(lpOTMW->otmpFullName) {
1502 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1503 len = WideCharToMultiByte(CP_ACP, 0,
1504 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1505 ptr, left, NULL, NULL);
1506 left -= len;
1507 } else
1508 lpOTM->otmpFullName = 0;
1510 assert(left == 0);
1512 ret = needed;
1514 end:
1515 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1516 HeapFree(GetProcessHeap(), 0, lpOTMW);
1518 return ret;
1522 /***********************************************************************
1523 * GetOutlineTextMetricsW [GDI32.@]
1525 UINT WINAPI GetOutlineTextMetricsW(
1526 HDC hdc, /* [in] Handle of device context */
1527 UINT cbData, /* [in] Size of metric data array */
1528 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1530 DC *dc = DC_GetDCPtr( hdc );
1531 UINT ret;
1533 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1534 if(!dc) return 0;
1536 if(dc->gdiFont)
1537 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1539 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1540 but really this should just be a return 0. */
1542 ret = sizeof(*lpOTM);
1543 if (lpOTM) {
1544 if(cbData < ret)
1545 ret = 0;
1546 else {
1547 memset(lpOTM, 0, ret);
1548 lpOTM->otmSize = sizeof(*lpOTM);
1549 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1551 Further fill of the structure not implemented,
1552 Needs real values for the structure members
1557 GDI_ReleaseObj(hdc);
1558 return ret;
1562 /***********************************************************************
1563 * GetCharWidth (GDI.350)
1565 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1566 LPINT16 buffer )
1568 BOOL retVal = FALSE;
1570 if( firstChar != lastChar )
1572 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1573 sizeof(INT)*(1 + (lastChar - firstChar)));
1574 if( buf32 )
1576 LPINT obuf32 = buf32;
1577 int i;
1579 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1580 if (retVal)
1582 for (i = firstChar; i <= lastChar; i++)
1583 *buffer++ = *buf32++;
1585 HeapFree(GetProcessHeap(), 0, obuf32);
1588 else /* happens quite often to warrant a special treatment */
1590 INT chWidth;
1591 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1592 *buffer = chWidth;
1594 return retVal;
1598 /***********************************************************************
1599 * GetCharWidthW (GDI32.@)
1600 * GetCharWidth32W (GDI32.@)
1602 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1603 LPINT buffer )
1605 UINT i, extra;
1606 BOOL ret = FALSE;
1607 DC * dc = DC_GetDCPtr( hdc );
1608 if (!dc) return FALSE;
1610 if (dc->gdiFont)
1611 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1612 else if (dc->funcs->pGetCharWidth)
1613 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1615 if (ret)
1617 /* convert device units to logical */
1619 extra = dc->vportExtX >> 1;
1620 for( i = firstChar; i <= lastChar; i++, buffer++ )
1621 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1622 ret = TRUE;
1624 GDI_ReleaseObj( hdc );
1625 return ret;
1629 /***********************************************************************
1630 * GetCharWidthA (GDI32.@)
1631 * GetCharWidth32A (GDI32.@)
1633 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1634 LPINT buffer )
1636 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1637 LPSTR str;
1638 LPWSTR wstr;
1639 BOOL ret = TRUE;
1641 if(count <= 0) return FALSE;
1643 str = HeapAlloc(GetProcessHeap(), 0, count);
1644 for(i = 0; i < count; i++)
1645 str[i] = (BYTE)(firstChar + i);
1647 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1649 for(i = 0; i < wlen; i++)
1651 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1653 ret = FALSE;
1654 break;
1656 buffer++;
1659 HeapFree(GetProcessHeap(), 0, str);
1660 HeapFree(GetProcessHeap(), 0, wstr);
1662 return ret;
1666 /* FIXME: all following APIs ******************************************/
1669 /***********************************************************************
1670 * SetMapperFlags (GDI.349)
1672 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1674 return SetMapperFlags( hDC, dwFlag );
1678 /***********************************************************************
1679 * SetMapperFlags (GDI32.@)
1681 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1683 DC *dc = DC_GetDCPtr( hDC );
1684 DWORD ret = 0;
1685 if(!dc) return 0;
1686 if(dc->funcs->pSetMapperFlags)
1687 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1688 else
1689 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1690 GDI_ReleaseObj( hDC );
1691 return ret;
1694 /***********************************************************************
1695 * GetAspectRatioFilterEx (GDI.486)
1697 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1699 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1700 return FALSE;
1703 /***********************************************************************
1704 * GetAspectRatioFilterEx (GDI32.@)
1706 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1708 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1709 return FALSE;
1712 /***********************************************************************
1713 * GetCharABCWidths (GDI.307)
1715 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1716 LPABC16 abc )
1718 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1719 int i;
1721 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1722 HeapFree(GetProcessHeap(),0,abc32);
1723 return FALSE;
1726 for (i=firstChar;i<=lastChar;i++) {
1727 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1728 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1729 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1731 HeapFree(GetProcessHeap(),0,abc32);
1732 return TRUE;
1736 /***********************************************************************
1737 * GetCharABCWidthsA (GDI32.@)
1739 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1740 LPABC abc )
1742 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1743 LPSTR str;
1744 LPWSTR wstr;
1745 BOOL ret = TRUE;
1747 if(count <= 0) return FALSE;
1749 str = HeapAlloc(GetProcessHeap(), 0, count);
1750 for(i = 0; i < count; i++)
1751 str[i] = (BYTE)(firstChar + i);
1753 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1755 for(i = 0; i < wlen; i++)
1757 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1759 ret = FALSE;
1760 break;
1762 abc++;
1765 HeapFree(GetProcessHeap(), 0, str);
1766 HeapFree(GetProcessHeap(), 0, wstr);
1768 return ret;
1772 /******************************************************************************
1773 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1775 * PARAMS
1776 * hdc [I] Handle of device context
1777 * firstChar [I] First character in range to query
1778 * lastChar [I] Last character in range to query
1779 * abc [O] Address of character-width structure
1781 * NOTES
1782 * Only works with TrueType fonts
1784 * RETURNS
1785 * Success: TRUE
1786 * Failure: FALSE
1788 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1789 LPABC abc )
1791 DC *dc = DC_GetDCPtr(hdc);
1792 int i;
1793 GLYPHMETRICS gm;
1794 BOOL ret = FALSE;
1796 if(dc->gdiFont) {
1797 for (i=firstChar;i<=lastChar;i++) {
1798 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1799 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1800 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1801 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1803 ret = TRUE;
1805 GDI_ReleaseObj(hdc);
1806 return ret;
1810 /***********************************************************************
1811 * GetGlyphOutline (GDI.309)
1813 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1814 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1815 LPVOID lpBuffer, const MAT2 *lpmat2 )
1817 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1818 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1819 return (DWORD)-1; /* failure */
1823 /***********************************************************************
1824 * GetGlyphOutlineA (GDI32.@)
1826 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1827 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1828 LPVOID lpBuffer, const MAT2 *lpmat2 )
1830 LPWSTR p = NULL;
1831 DWORD ret;
1832 UINT c;
1834 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1835 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1836 c = p[0];
1837 } else
1838 c = uChar;
1839 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1840 lpmat2);
1841 if(p)
1842 HeapFree(GetProcessHeap(), 0, p);
1843 return ret;
1846 /***********************************************************************
1847 * GetGlyphOutlineW (GDI32.@)
1849 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1850 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1851 LPVOID lpBuffer, const MAT2 *lpmat2 )
1853 DC *dc = DC_GetDCPtr(hdc);
1854 DWORD ret;
1856 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1857 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1859 if(!dc) return GDI_ERROR;
1861 if(dc->gdiFont)
1862 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1863 cbBuffer, lpBuffer, lpmat2);
1864 else
1865 ret = GDI_ERROR;
1867 GDI_ReleaseObj(hdc);
1868 return ret;
1871 /***********************************************************************
1872 * CreateScalableFontResource (GDI.310)
1874 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1875 LPCSTR lpszResourceFile,
1876 LPCSTR fontFile, LPCSTR path )
1878 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1879 fontFile, path );
1882 /***********************************************************************
1883 * CreateScalableFontResourceA (GDI32.@)
1885 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1886 LPCSTR lpszResourceFile,
1887 LPCSTR lpszFontFile,
1888 LPCSTR lpszCurrentPath )
1890 /* fHidden=1 - only visible for the calling app, read-only, not
1891 * enumbered with EnumFonts/EnumFontFamilies
1892 * lpszCurrentPath can be NULL
1894 FIXME("(%ld,%s,%s,%s): stub\n",
1895 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1896 debugstr_a(lpszCurrentPath) );
1897 return FALSE; /* create failed */
1900 /***********************************************************************
1901 * CreateScalableFontResourceW (GDI32.@)
1903 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1904 LPCWSTR lpszResourceFile,
1905 LPCWSTR lpszFontFile,
1906 LPCWSTR lpszCurrentPath )
1908 FIXME("(%ld,%p,%p,%p): stub\n",
1909 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1910 return FALSE; /* create failed */
1914 /*************************************************************************
1915 * GetRasterizerCaps (GDI.313)
1917 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1919 return GetRasterizerCaps( lprs, cbNumBytes );
1923 /*************************************************************************
1924 * GetRasterizerCaps (GDI32.@)
1926 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1928 lprs->nSize = sizeof(RASTERIZER_STATUS);
1929 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1930 lprs->nLanguageID = 0;
1931 return TRUE;
1935 /*************************************************************************
1936 * GetKerningPairs (GDI.332)
1939 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1940 LPKERNINGPAIR16 lpKerningPairs )
1942 /* At this time kerning is ignored (set to 0) */
1943 int i;
1944 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1945 if (lpKerningPairs)
1946 for (i = 0; i < cPairs; i++)
1947 lpKerningPairs[i].iKernAmount = 0;
1948 /* FIXME: Should this function call SetLastError (0)? This is yet another
1949 * Microsoft function that can return 0 on success or failure
1951 return 0;
1956 /*************************************************************************
1957 * GetKerningPairsA (GDI32.@)
1959 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1960 LPKERNINGPAIR lpKerningPairs )
1962 int i;
1963 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1964 for (i = 0; i < cPairs; i++)
1965 lpKerningPairs[i].iKernAmount = 0;
1966 return 0;
1970 /*************************************************************************
1971 * GetKerningPairsW (GDI32.@)
1973 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1974 LPKERNINGPAIR lpKerningPairs )
1976 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1979 /*************************************************************************
1980 * TranslateCharsetInfo [GDI32.@]
1981 * TranslateCharsetInfo [USER32.@]
1983 * Fills a CHARSETINFO structure for a character set, code page, or
1984 * font. This allows making the correspondance between different labelings
1985 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1986 * of the same encoding.
1988 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1989 * only one codepage should be set in *lpSrc.
1991 * RETURNS
1992 * TRUE on success, FALSE on failure.
1995 BOOL WINAPI TranslateCharsetInfo(
1996 LPDWORD lpSrc, /* [in]
1997 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1998 if flags == TCI_SRCCHARSET: a character set value
1999 if flags == TCI_SRCCODEPAGE: a code page value
2001 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2002 DWORD flags /* [in] determines interpretation of lpSrc */
2004 int index = 0;
2005 switch (flags) {
2006 case TCI_SRCFONTSIG:
2007 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2008 break;
2009 case TCI_SRCCODEPAGE:
2010 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2011 break;
2012 case TCI_SRCCHARSET:
2013 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2014 break;
2015 default:
2016 return FALSE;
2018 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2019 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2020 return TRUE;
2023 /*************************************************************************
2024 * GetFontLanguageInfo (GDI32.@)
2026 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
2027 /* return value 0 is correct for most cases anyway */
2028 FIXME("(%x):stub!\n", hdc);
2029 return 0;
2032 /*************************************************************************
2033 * GetFontLanguageInfo (GDI.616)
2035 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
2036 /* return value 0 is correct for most cases anyway */
2037 FIXME("(%x):stub!\n",hdc);
2038 return 0;
2041 /*************************************************************************
2042 * GetFontData [GDI32.@] Retrieve data for TrueType font
2044 * RETURNS
2046 * success: Number of bytes returned
2047 * failure: GDI_ERROR
2049 * NOTES
2051 * Calls SetLastError()
2054 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2055 LPVOID buffer, DWORD length)
2057 DC *dc = DC_GetDCPtr(hdc);
2058 DWORD ret = GDI_ERROR;
2060 if(!dc) return GDI_ERROR;
2062 if(dc->gdiFont)
2063 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2065 GDI_ReleaseObj(hdc);
2066 return ret;
2069 /*************************************************************************
2070 * GetFontData [GDI.311]
2073 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2074 LPVOID lpvBuffer, DWORD cbData)
2076 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2079 /*************************************************************************
2080 * GetGlyphIndicesA [GDI32.@]
2082 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2083 LPWORD pgi, DWORD flags)
2085 DWORD ret;
2086 WCHAR *lpstrW;
2087 INT countW;
2089 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2090 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2092 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2093 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2094 HeapFree(GetProcessHeap(), 0, lpstrW);
2096 return ret;
2099 /*************************************************************************
2100 * GetGlyphIndicesW [GDI32.@]
2102 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2103 LPWORD pgi, DWORD flags)
2105 DC *dc = DC_GetDCPtr(hdc);
2106 DWORD ret = GDI_ERROR;
2108 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2109 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2111 if(!dc) return GDI_ERROR;
2113 if(dc->gdiFont)
2114 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2116 GDI_ReleaseObj(hdc);
2117 return ret;
2120 /*************************************************************************
2121 * GetCharacterPlacementA [GDI32.@]
2123 * NOTES:
2124 * the web browser control of ie4 calls this with dwFlags=0
2126 DWORD WINAPI
2127 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2128 INT nMaxExtent, GCP_RESULTSA *lpResults,
2129 DWORD dwFlags)
2131 WCHAR *lpStringW;
2132 INT uCountW;
2133 GCP_RESULTSW resultsW;
2134 DWORD ret;
2135 UINT font_cp;
2137 TRACE("%s, %d, %d, 0x%08lx\n",
2138 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2140 /* both structs are equal in size */
2141 memcpy(&resultsW, lpResults, sizeof(resultsW));
2143 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2144 if(lpResults->lpOutString)
2145 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2146 else
2147 resultsW.lpOutString = NULL;
2149 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2151 if(lpResults->lpOutString)
2152 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2153 lpResults->lpOutString, uCount, NULL, NULL );
2155 HeapFree(GetProcessHeap(), 0, lpStringW);
2156 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2158 return ret;
2161 /*************************************************************************
2162 * GetCharacterPlacementW [GDI32.@]
2164 DWORD WINAPI
2165 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
2166 INT nMaxExtent, GCP_RESULTSW *lpResults,
2167 DWORD dwFlags)
2169 DWORD ret=0;
2170 SIZE size;
2171 UINT i, nSet;
2173 TRACE("%s, %d, %d, 0x%08lx\n",
2174 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2176 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2177 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2178 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2179 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2180 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2182 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
2183 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2184 if(lpResults->lpClass) FIXME("classes not implemented\n");
2186 /* FIXME: reordering not implemented */
2187 /* copy will do if the GCP_REORDER flag is not set */
2188 if(lpResults->lpOutString)
2189 lstrcpynW(lpResults->lpOutString, lpString, uCount);
2191 nSet = (UINT)uCount;
2192 if(nSet > lpResults->nGlyphs)
2193 nSet = lpResults->nGlyphs;
2195 /* return number of initialized fields */
2196 lpResults->nGlyphs = nSet;
2198 if(lpResults->lpOrder)
2200 for(i = 0; i < nSet; i++)
2201 lpResults->lpOrder[i] = i;
2204 if (lpResults->lpDx)
2206 int c;
2207 for (i = 0; i < nSet; i++)
2209 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2210 lpResults->lpDx[i]= c;
2214 if(lpResults->lpGlyphs)
2215 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2217 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2218 ret = MAKELONG(size.cx, size.cy);
2220 return ret;
2223 /*************************************************************************
2224 * GetCharABCWidthsFloatA [GDI32.@]
2226 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2227 LPABCFLOAT lpABCF)
2229 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2230 return 0;
2233 /*************************************************************************
2234 * GetCharABCWidthsFloatW [GDI32.@]
2236 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2237 UINT iLastChar, LPABCFLOAT lpABCF)
2239 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2240 return 0;
2243 /*************************************************************************
2244 * GetCharWidthFloatA [GDI32.@]
2246 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2247 UINT iLastChar, PFLOAT pxBuffer)
2249 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2250 return 0;
2253 /*************************************************************************
2254 * GetCharWidthFloatW [GDI32.@]
2256 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2257 UINT iLastChar, PFLOAT pxBuffer)
2259 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2260 return 0;
2264 /***********************************************************************
2266 * Font Resource API *
2268 ***********************************************************************/
2269 /***********************************************************************
2270 * AddFontResource (GDI.119)
2272 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2274 * FIXME: Load header and find the best-matching font in the fontList;
2275 * fixup dfPoints if all metrics are identical, otherwise create
2276 * new fontAlias. When soft font support is ready this will
2277 * simply create a new fontResource ('filename' will go into
2278 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
2279 * flag set.
2281 INT16 WINAPI AddFontResource16( LPCSTR filename )
2283 return AddFontResourceA( filename );
2287 /***********************************************************************
2288 * AddFontResourceA (GDI32.@)
2290 INT WINAPI AddFontResourceA( LPCSTR str )
2292 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2293 "this font manually.\n", debugres_a(str));
2294 return 1;
2298 /***********************************************************************
2299 * AddFontResourceW (GDI32.@)
2301 INT WINAPI AddFontResourceW( LPCWSTR str )
2303 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2304 "this font manually.\n", debugres_w(str));
2305 return 1;
2308 /***********************************************************************
2309 * RemoveFontResource (GDI.136)
2311 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2313 FIXME("(%s): stub\n", debugres_a(str));
2314 return TRUE;
2318 /***********************************************************************
2319 * RemoveFontResourceA (GDI32.@)
2321 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2323 /* This is how it should look like */
2325 fontResource** ppfr;
2326 BOOL32 retVal = FALSE;
2328 EnterCriticalSection( &crtsc_fonts_X11 );
2329 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2330 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2332 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2333 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2335 if( (*ppfr)->fo_count )
2336 (*ppfr)->fr_flags |= FR_REMOVED;
2337 else
2338 XFONT_RemoveFontResource( ppfr );
2340 retVal = TRUE;
2342 LeaveCriticalSection( &crtsc_fonts_X11 );
2343 return retVal;
2345 FIXME("(%s): stub\n", debugres_a(str));
2346 return TRUE;
2350 /***********************************************************************
2351 * RemoveFontResourceW (GDI32.@)
2353 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2355 FIXME("(%s): stub\n", debugres_w(str) );
2356 return TRUE;