Implemented a MP3 decoder (based on mpglib).
[wine/multimedia.git] / objects / font.c
blob7a3c7529f50d91fe0050e66394ce25a4deee59cd
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 "wine/debug.h"
30 #include "gdi.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
54 typedef struct
56 GDIOBJHDR header;
57 LOGFONTW logfont;
58 } FONTOBJ;
60 typedef struct
62 LPLOGFONT16 lpLogFontParam;
63 FONTENUMPROCEX16 lpEnumFunc;
64 LPARAM lpData;
66 LPNEWTEXTMETRICEX16 lpTextMetric;
67 LPENUMLOGFONTEX16 lpLogFont;
68 SEGPTR segTextMetric;
69 SEGPTR segLogFont;
70 HDC hdc;
71 DC *dc;
72 PHYSDEV physDev;
73 } fontEnum16;
75 typedef struct
77 LPLOGFONTW lpLogFontParam;
78 FONTENUMPROCEXW lpEnumFunc;
79 LPARAM lpData;
80 DWORD dwFlags;
81 HDC hdc;
82 DC *dc;
83 PHYSDEV physDev;
84 } fontEnum32;
87 * For TranslateCharsetInfo
89 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
90 #define MAXTCIINDEX 32
91 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
92 /* ANSI */
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 /* reserved by ANSI */
102 { DEFAULT_CHARSET, 0, FS(0)},
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)},
110 /* ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
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,
217 LF_FACESIZE);
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 * CreateFontIndirect (GDI.57)
459 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
461 LOGFONTW lfW;
463 if(plf16) {
464 FONT_LogFont16ToW( plf16, &lfW );
465 return CreateFontIndirectW( &lfW );
466 } else {
467 return CreateFontIndirectW( NULL );
472 /***********************************************************************
473 * CreateFontIndirectA (GDI32.@)
475 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
477 LOGFONTW lfW;
479 if (plfA) {
480 FONT_LogFontAToW( plfA, &lfW );
481 return CreateFontIndirectW( &lfW );
482 } else
483 return CreateFontIndirectW( NULL );
487 /***********************************************************************
488 * CreateFontIndirectW (GDI32.@)
490 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
492 HFONT hFont = 0;
494 if (plf)
496 FONTOBJ* fontPtr;
497 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
499 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
501 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
502 plf->lfHeight, plf->lfWidth,
503 plf->lfEscapement, plf->lfOrientation,
504 plf->lfPitchAndFamily,
505 debugstr_w(plf->lfFaceName),
506 plf->lfWeight > 400 ? "Bold" : "",
507 plf->lfItalic ? "Italic" : "", hFont);
509 if (plf->lfEscapement != plf->lfOrientation) {
510 /* this should really depend on whether GM_ADVANCED is set */
511 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
512 WARN("orientation angle %f set to "
513 "escapement angle %f for new font %04x\n",
514 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
516 GDI_ReleaseObj( hFont );
519 else WARN("(NULL) => NULL\n");
521 return hFont;
524 /***********************************************************************
525 * CreateFont (GDI.56)
527 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
528 INT16 weight, BYTE italic, BYTE underline,
529 BYTE strikeout, BYTE charset, BYTE outpres,
530 BYTE clippres, BYTE quality, BYTE pitch,
531 LPCSTR name )
533 LOGFONT16 logfont;
535 logfont.lfHeight = height;
536 logfont.lfWidth = width;
537 logfont.lfEscapement = esc;
538 logfont.lfOrientation = orient;
539 logfont.lfWeight = weight;
540 logfont.lfItalic = italic;
541 logfont.lfUnderline = underline;
542 logfont.lfStrikeOut = strikeout;
543 logfont.lfCharSet = charset;
544 logfont.lfOutPrecision = outpres;
545 logfont.lfClipPrecision = clippres;
546 logfont.lfQuality = quality;
547 logfont.lfPitchAndFamily = pitch;
549 if (name)
550 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
551 else
552 logfont.lfFaceName[0] = '\0';
554 return CreateFontIndirect16( &logfont );
557 /*************************************************************************
558 * CreateFontA (GDI32.@)
560 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
561 INT orient, INT weight, DWORD italic,
562 DWORD underline, DWORD strikeout, DWORD charset,
563 DWORD outpres, DWORD clippres, DWORD quality,
564 DWORD pitch, LPCSTR name )
566 LOGFONTA logfont;
568 logfont.lfHeight = height;
569 logfont.lfWidth = width;
570 logfont.lfEscapement = esc;
571 logfont.lfOrientation = orient;
572 logfont.lfWeight = weight;
573 logfont.lfItalic = italic;
574 logfont.lfUnderline = underline;
575 logfont.lfStrikeOut = strikeout;
576 logfont.lfCharSet = charset;
577 logfont.lfOutPrecision = outpres;
578 logfont.lfClipPrecision = clippres;
579 logfont.lfQuality = quality;
580 logfont.lfPitchAndFamily = pitch;
582 if (name)
583 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
584 else
585 logfont.lfFaceName[0] = '\0';
587 return CreateFontIndirectA( &logfont );
590 /*************************************************************************
591 * CreateFontW (GDI32.@)
593 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
594 INT orient, INT weight, DWORD italic,
595 DWORD underline, DWORD strikeout, DWORD charset,
596 DWORD outpres, DWORD clippres, DWORD quality,
597 DWORD pitch, LPCWSTR name )
599 LOGFONTW logfont;
601 logfont.lfHeight = height;
602 logfont.lfWidth = width;
603 logfont.lfEscapement = esc;
604 logfont.lfOrientation = orient;
605 logfont.lfWeight = weight;
606 logfont.lfItalic = italic;
607 logfont.lfUnderline = underline;
608 logfont.lfStrikeOut = strikeout;
609 logfont.lfCharSet = charset;
610 logfont.lfOutPrecision = outpres;
611 logfont.lfClipPrecision = clippres;
612 logfont.lfQuality = quality;
613 logfont.lfPitchAndFamily = pitch;
615 if (name)
616 lstrcpynW(logfont.lfFaceName, name,
617 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
618 else
619 logfont.lfFaceName[0] = '\0';
621 return CreateFontIndirectW( &logfont );
625 /***********************************************************************
626 * FONT_SelectObject
628 * If the driver supports vector fonts we create a gdi font first and
629 * then call the driver to give it a chance to supply its own device
630 * font. If the driver wants to do this it returns TRUE and we can
631 * delete the gdi font, if the driver wants to use the gdi font it
632 * should return FALSE, to signal an error return GDI_ERROR. For
633 * drivers that don't support vector fonts they must supply their own
634 * font.
636 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
638 HGDIOBJ ret = 0;
639 DC *dc = DC_GetDCPtr( hdc );
641 if (!dc) return 0;
643 if (dc->hFont != handle || dc->gdiFont == NULL)
645 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
646 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
649 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
651 if (ret && dc->gdiFont) dc->gdiFont = 0;
653 if (ret == GDI_ERROR)
654 ret = 0; /* SelectObject returns 0 on error */
655 else
657 ret = dc->hFont;
658 dc->hFont = handle;
660 GDI_ReleaseObj( hdc );
661 return ret;
665 /***********************************************************************
666 * FONT_GetObject16
668 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
670 FONTOBJ *font = obj;
671 LOGFONT16 lf16;
673 FONT_LogFontWTo16( &font->logfont, &lf16 );
675 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
676 memcpy( buffer, &lf16, count );
677 return count;
680 /***********************************************************************
681 * FONT_GetObjectA
683 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
685 FONTOBJ *font = obj;
686 LOGFONTA lfA;
688 FONT_LogFontWToA( &font->logfont, &lfA );
690 if (count > sizeof(lfA)) count = sizeof(lfA);
691 memcpy( buffer, &lfA, count );
692 return count;
695 /***********************************************************************
696 * FONT_GetObjectW
698 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
700 FONTOBJ *font = obj;
701 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
702 memcpy( buffer, &font->logfont, count );
703 return count;
707 /***********************************************************************
708 * FONT_DeleteObject
710 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
712 WineEngDestroyFontInstance( handle );
713 return GDI_FreeObject( handle, obj );
717 /***********************************************************************
718 * FONT_EnumInstance16
720 * Called by the device driver layer to pass font info
721 * down to the application.
723 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
724 DWORD fType, LPARAM lp )
726 fontEnum16 *pfe = (fontEnum16*)lp;
727 INT ret = 1;
728 DC *dc;
730 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
731 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
733 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
734 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
735 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
737 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
738 (UINT16)fType, (LPARAM)pfe->lpData );
739 /* get the lock again and make sure the DC is still valid */
740 dc = DC_GetDCPtr( pfe->hdc );
741 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
743 if (dc) GDI_ReleaseObj( pfe->hdc );
744 pfe->hdc = 0; /* make sure we don't try to release it later on */
745 ret = 0;
748 return ret;
751 /***********************************************************************
752 * FONT_EnumInstance
754 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
755 DWORD fType, LPARAM lp )
757 fontEnum32 *pfe = (fontEnum32*)lp;
758 INT ret = 1;
759 DC *dc;
761 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
762 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
763 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
765 /* convert font metrics */
766 ENUMLOGFONTEXA logfont;
767 NEWTEXTMETRICEXA tmA;
769 pfe->dwFlags |= ENUM_CALLED;
770 if (!(pfe->dwFlags & ENUM_UNICODE))
772 FONT_EnumLogFontExWToA( plf, &logfont);
773 FONT_NewTextMetricExWToA( ptm, &tmA );
774 plf = (LPENUMLOGFONTEXW)&logfont;
775 ptm = (LPNEWTEXTMETRICEXW)&tmA;
777 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
779 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
781 /* get the lock again and make sure the DC is still valid */
782 dc = DC_GetDCPtr( pfe->hdc );
783 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
785 if (dc) GDI_ReleaseObj( pfe->hdc );
786 pfe->hdc = 0; /* make sure we don't try to release it later on */
787 ret = 0;
790 return ret;
793 /***********************************************************************
794 * EnumFontFamiliesEx (GDI.613)
796 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
797 FONTENUMPROCEX16 efproc, LPARAM lParam,
798 DWORD dwFlags)
800 fontEnum16 fe16;
801 INT16 retVal = 0;
802 DC* dc = DC_GetDCPtr( hDC );
804 if (!dc) return 0;
805 fe16.hdc = hDC;
806 fe16.dc = dc;
807 fe16.physDev = dc->physDev;
809 if (dc->funcs->pEnumDeviceFonts)
811 NEWTEXTMETRICEX16 tm16;
812 ENUMLOGFONTEX16 lf16;
813 LOGFONTW lfW;
814 FONT_LogFont16ToW(plf, &lfW);
816 fe16.lpLogFontParam = plf;
817 fe16.lpEnumFunc = efproc;
818 fe16.lpData = lParam;
819 fe16.lpTextMetric = &tm16;
820 fe16.lpLogFont = &lf16;
821 fe16.segTextMetric = MapLS( &tm16 );
822 fe16.segLogFont = MapLS( &lf16 );
824 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
825 FONT_EnumInstance16, (LPARAM)&fe16 );
826 UnMapLS( fe16.segTextMetric );
827 UnMapLS( fe16.segLogFont );
829 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
830 return retVal;
833 /***********************************************************************
834 * FONT_EnumFontFamiliesEx
836 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
837 FONTENUMPROCEXW efproc,
838 LPARAM lParam, DWORD dwUnicode)
840 INT ret = 1, ret2;
841 DC *dc = DC_GetDCPtr( hDC );
842 fontEnum32 fe32;
843 BOOL enum_gdi_fonts;
845 if (!dc) return 0;
847 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
848 plf->lfCharSet);
849 fe32.lpLogFontParam = plf;
850 fe32.lpEnumFunc = efproc;
851 fe32.lpData = lParam;
852 fe32.dwFlags = dwUnicode;
853 fe32.hdc = hDC;
854 fe32.dc = dc;
855 fe32.physDev = dc->physDev;
857 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
859 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
861 ret = 0;
862 goto done;
865 if (enum_gdi_fonts)
866 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
867 fe32.dwFlags &= ~ENUM_CALLED;
868 if (ret && dc->funcs->pEnumDeviceFonts) {
869 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
870 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
871 ret = ret2;
873 done:
874 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
875 return ret;
878 /***********************************************************************
879 * EnumFontFamiliesExW (GDI32.@)
881 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
882 FONTENUMPROCEXW efproc,
883 LPARAM lParam, DWORD dwFlags )
885 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
888 /***********************************************************************
889 * EnumFontFamiliesExA (GDI32.@)
891 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
892 FONTENUMPROCEXA efproc,
893 LPARAM lParam, DWORD dwFlags)
895 LOGFONTW lfW;
896 FONT_LogFontAToW( plf, &lfW );
898 return FONT_EnumFontFamiliesEx( hDC, &lfW,
899 (FONTENUMPROCEXW)efproc, lParam, 0);
902 /***********************************************************************
903 * EnumFontFamilies (GDI.330)
905 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
906 FONTENUMPROC16 efproc, LPARAM lpData )
908 LOGFONT16 lf;
910 lf.lfCharSet = DEFAULT_CHARSET;
911 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
912 else lf.lfFaceName[0] = '\0';
914 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
917 /***********************************************************************
918 * EnumFontFamiliesA (GDI32.@)
920 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
921 FONTENUMPROCA efproc, LPARAM lpData )
923 LOGFONTA lf;
925 lf.lfCharSet = DEFAULT_CHARSET;
926 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
927 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
929 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
932 /***********************************************************************
933 * EnumFontFamiliesW (GDI32.@)
935 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
936 FONTENUMPROCW efproc, LPARAM lpData )
938 LOGFONTW lf;
940 lf.lfCharSet = DEFAULT_CHARSET;
941 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
942 else lf.lfFaceName[0] = 0;
944 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
947 /***********************************************************************
948 * EnumFonts (GDI.70)
950 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
951 LPARAM lpData )
953 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
956 /***********************************************************************
957 * EnumFontsA (GDI32.@)
959 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
960 LPARAM lpData )
962 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
965 /***********************************************************************
966 * EnumFontsW (GDI32.@)
968 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
969 LPARAM lpData )
971 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
975 /***********************************************************************
976 * GetTextCharacterExtra (GDI.89)
978 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
980 return (INT16)GetTextCharacterExtra( hdc );
984 /***********************************************************************
985 * GetTextCharacterExtra (GDI32.@)
987 INT WINAPI GetTextCharacterExtra( HDC hdc )
989 INT ret;
990 DC *dc = DC_GetDCPtr( hdc );
991 if (!dc) return 0;
992 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
993 / dc->vportExtX );
994 GDI_ReleaseObj( hdc );
995 return ret;
999 /***********************************************************************
1000 * SetTextCharacterExtra (GDI.8)
1002 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
1004 return (INT16)SetTextCharacterExtra( hdc, extra );
1008 /***********************************************************************
1009 * SetTextCharacterExtra (GDI32.@)
1011 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
1013 INT prev;
1014 DC * dc = DC_GetDCPtr( hdc );
1015 if (!dc) return 0;
1016 if (dc->funcs->pSetTextCharacterExtra)
1017 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
1018 else
1020 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
1021 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
1022 dc->charExtra = abs(extra);
1024 GDI_ReleaseObj( hdc );
1025 return prev;
1029 /***********************************************************************
1030 * SetTextJustification (GDI.10)
1032 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
1034 return SetTextJustification( hdc, extra, breaks );
1038 /***********************************************************************
1039 * SetTextJustification (GDI32.@)
1041 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
1043 BOOL ret = TRUE;
1044 DC * dc = DC_GetDCPtr( hdc );
1045 if (!dc) return FALSE;
1046 if (dc->funcs->pSetTextJustification)
1047 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
1048 else
1050 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
1051 if (!extra) breaks = 0;
1052 dc->breakTotalExtra = extra;
1053 dc->breakCount = breaks;
1054 if (breaks)
1056 dc->breakExtra = extra / breaks;
1057 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
1059 else
1061 dc->breakExtra = 0;
1062 dc->breakRem = 0;
1065 GDI_ReleaseObj( hdc );
1066 return ret;
1070 /***********************************************************************
1071 * GetTextFace (GDI.92)
1073 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
1075 return GetTextFaceA(hdc,count,name);
1078 /***********************************************************************
1079 * GetTextFaceA (GDI32.@)
1081 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
1083 INT res = GetTextFaceW(hdc, 0, NULL);
1084 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
1085 GetTextFaceW( hdc, res, nameW );
1087 if (name)
1088 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
1089 NULL, NULL);
1090 else
1091 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
1092 HeapFree( GetProcessHeap(), 0, nameW );
1093 return res;
1096 /***********************************************************************
1097 * GetTextFaceW (GDI32.@)
1099 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
1101 FONTOBJ *font;
1102 INT ret = 0;
1104 DC * dc = DC_GetDCPtr( hdc );
1105 if (!dc) return 0;
1107 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1109 if (name)
1111 lstrcpynW( name, font->logfont.lfFaceName, count );
1112 ret = strlenW(name);
1114 else ret = strlenW(font->logfont.lfFaceName) + 1;
1115 GDI_ReleaseObj( dc->hFont );
1117 GDI_ReleaseObj( hdc );
1118 return ret;
1122 /***********************************************************************
1123 * GetTextExtent (GDI.91)
1125 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1127 SIZE16 size;
1128 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1129 return MAKELONG( size.cx, size.cy );
1133 /***********************************************************************
1134 * GetTextExtentPoint (GDI.471)
1136 * FIXME: Should this have a bug for compatibility?
1137 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1138 * bugs (-> MSDN KB q147647.txt).
1140 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1141 LPSIZE16 size )
1143 SIZE size32;
1144 BOOL ret;
1145 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1146 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1147 size->cx = size32.cx;
1148 size->cy = size32.cy;
1149 return (BOOL16)ret;
1153 /***********************************************************************
1154 * GetTextExtentPoint32A (GDI32.@)
1156 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1157 LPSIZE size )
1159 BOOL ret = FALSE;
1160 INT wlen;
1161 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1163 if (p) {
1164 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1165 HeapFree( GetProcessHeap(), 0, p );
1168 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1169 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1170 return ret;
1174 /***********************************************************************
1175 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1177 * Computes width and height of the specified string.
1179 * RETURNS
1180 * Success: TRUE
1181 * Failure: FALSE
1183 BOOL WINAPI GetTextExtentPoint32W(
1184 HDC hdc, /* [in] Handle of device context */
1185 LPCWSTR str, /* [in] Address of text string */
1186 INT count, /* [in] Number of characters in string */
1187 LPSIZE size) /* [out] Address of structure for string size */
1189 BOOL ret = FALSE;
1190 DC * dc = DC_GetDCPtr( hdc );
1191 if (!dc) return FALSE;
1193 if(dc->gdiFont) {
1194 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1195 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1196 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1198 else if(dc->funcs->pGetTextExtentPoint)
1199 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1201 GDI_ReleaseObj( hdc );
1203 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1204 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1205 return ret;
1208 /***********************************************************************
1209 * GetTextExtentPointI [GDI32.@]
1211 * Computes width and height of the array of glyph indices.
1213 * RETURNS
1214 * Success: TRUE
1215 * Failure: FALSE
1217 BOOL WINAPI GetTextExtentPointI(
1218 HDC hdc, /* [in] Handle of device context */
1219 const WORD *indices, /* [in] Address of glyph index array */
1220 INT count, /* [in] Number of glyphs in array */
1221 LPSIZE size) /* [out] Address of structure for string size */
1223 BOOL ret = FALSE;
1224 DC * dc = DC_GetDCPtr( hdc );
1225 if (!dc) return FALSE;
1227 if(dc->gdiFont) {
1228 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1229 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1230 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1232 else if(dc->funcs->pGetTextExtentPoint) {
1233 FIXME("calling GetTextExtentPoint\n");
1234 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1237 GDI_ReleaseObj( hdc );
1239 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1240 hdc, indices, count, size, size->cx, size->cy );
1241 return ret;
1245 /***********************************************************************
1246 * GetTextExtentPointA (GDI32.@)
1248 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1249 LPSIZE size )
1251 TRACE("not bug compatible.\n");
1252 return GetTextExtentPoint32A( hdc, str, count, size );
1255 /***********************************************************************
1256 * GetTextExtentPointW (GDI32.@)
1258 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1259 LPSIZE size )
1261 TRACE("not bug compatible.\n");
1262 return GetTextExtentPoint32W( hdc, str, count, size );
1266 /***********************************************************************
1267 * GetTextExtentExPointA (GDI32.@)
1269 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1270 INT maxExt, LPINT lpnFit,
1271 LPINT alpDx, LPSIZE size )
1273 BOOL ret;
1274 INT wlen;
1275 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1276 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1277 HeapFree( GetProcessHeap(), 0, p );
1278 return ret;
1282 /***********************************************************************
1283 * GetTextExtentExPointW (GDI32.@)
1285 * Return the size of the string as it would be if it was output properly by
1286 * e.g. TextOut.
1288 * This should include
1289 * - Intercharacter spacing
1290 * - justification spacing (not yet done)
1291 * - kerning? see below
1293 * Kerning. Since kerning would be carried out by the rendering code it should
1294 * be done by the driver. However they don't support it yet. Also I am not
1295 * yet persuaded that (certainly under Win95) any kerning is actually done.
1297 * str: According to MSDN this should be null-terminated. That is not true; a
1298 * null will not terminate it early.
1299 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1300 * than count. I have seen it be either the size of the full string or
1301 * 1 less than the size of the full string. I have not seen it bear any
1302 * resemblance to the portion that would fit.
1303 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1304 * trailing intercharacter spacing and any trailing justification.
1306 * FIXME
1307 * Currently we do this by measuring each character etc. We should do it by
1308 * passing the request to the driver, perhaps by extending the
1309 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1310 * thinking about kerning issues and rounding issues in the justification.
1313 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1314 INT maxExt, LPINT lpnFit,
1315 LPINT alpDx, LPSIZE size )
1317 int index, nFit, extent;
1318 SIZE tSize;
1319 BOOL ret = FALSE;
1321 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1323 size->cx = size->cy = nFit = extent = 0;
1324 for(index = 0; index < count; index++)
1326 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1327 /* GetTextExtentPoint includes intercharacter spacing. */
1328 /* FIXME - justification needs doing yet. Remember that the base
1329 * data will not be in logical coordinates.
1331 extent += tSize.cx;
1332 if( !lpnFit || extent <= maxExt )
1333 /* It is allowed to be equal. */
1335 nFit++;
1336 if( alpDx ) alpDx[index] = extent;
1338 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1339 str++;
1341 size->cx = extent;
1342 if(lpnFit) *lpnFit = nFit;
1343 ret = TRUE;
1345 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1347 done:
1348 return ret;
1351 /***********************************************************************
1352 * GetTextMetrics (GDI.93)
1354 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1356 TEXTMETRICW tm32;
1358 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1359 FONT_TextMetricWTo16( &tm32, metrics );
1360 return TRUE;
1364 /***********************************************************************
1365 * GetTextMetricsA (GDI32.@)
1367 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1369 TEXTMETRICW tm32;
1371 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1372 FONT_TextMetricWToA( &tm32, metrics );
1373 return TRUE;
1376 /***********************************************************************
1377 * GetTextMetricsW (GDI32.@)
1379 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1381 BOOL ret = FALSE;
1382 DC * dc = DC_GetDCPtr( hdc );
1383 if (!dc) return FALSE;
1385 if (dc->gdiFont)
1386 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1387 else if (dc->funcs->pGetTextMetrics)
1388 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1390 if (ret)
1392 /* device layer returns values in device units
1393 * therefore we have to convert them to logical */
1395 #define WDPTOLP(x) ((x<0)? \
1396 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1397 (abs((x)*dc->wndExtX/dc->vportExtX)))
1398 #define HDPTOLP(y) ((y<0)? \
1399 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1400 (abs((y)*dc->wndExtY/dc->vportExtY)))
1402 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1403 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1404 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1405 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1406 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1407 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1408 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1409 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1410 ret = TRUE;
1412 TRACE("text metrics:\n"
1413 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1414 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1415 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1416 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1417 " PitchAndFamily = %02x\n"
1418 " --------------------\n"
1419 " InternalLeading = %li\n"
1420 " Ascent = %li\n"
1421 " Descent = %li\n"
1422 " Height = %li\n",
1423 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1424 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1425 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1426 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1427 metrics->tmPitchAndFamily,
1428 metrics->tmInternalLeading,
1429 metrics->tmAscent,
1430 metrics->tmDescent,
1431 metrics->tmHeight );
1433 GDI_ReleaseObj( hdc );
1434 return ret;
1438 /***********************************************************************
1439 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1441 * NOTES
1442 * lpOTM should be LPOUTLINETEXTMETRIC
1444 * RETURNS
1445 * Success: Non-zero or size of required buffer
1446 * Failure: 0
1448 UINT16 WINAPI GetOutlineTextMetrics16(
1449 HDC16 hdc, /* [in] Handle of device context */
1450 UINT16 cbData, /* [in] Size of metric data array */
1451 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1453 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1454 return 0;
1458 /***********************************************************************
1459 * GetOutlineTextMetricsA (GDI32.@)
1460 * Gets metrics for TrueType fonts.
1463 * RETURNS
1464 * Success: Non-zero or size of required buffer
1465 * Failure: 0
1467 UINT WINAPI GetOutlineTextMetricsA(
1468 HDC hdc, /* [in] Handle of device context */
1469 UINT cbData, /* [in] Size of metric data array */
1470 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1472 char buf[512], *ptr;
1473 UINT ret, needed;
1474 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1475 INT left, len;
1477 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1478 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1479 return 0;
1480 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1481 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1484 needed = sizeof(OUTLINETEXTMETRICA);
1485 if(lpOTMW->otmpFamilyName)
1486 needed += WideCharToMultiByte(CP_ACP, 0,
1487 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1488 NULL, 0, NULL, NULL);
1489 if(lpOTMW->otmpFaceName)
1490 needed += WideCharToMultiByte(CP_ACP, 0,
1491 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1492 NULL, 0, NULL, NULL);
1493 if(lpOTMW->otmpStyleName)
1494 needed += WideCharToMultiByte(CP_ACP, 0,
1495 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1496 NULL, 0, NULL, NULL);
1497 if(lpOTMW->otmpFullName)
1498 needed += WideCharToMultiByte(CP_ACP, 0,
1499 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1500 NULL, 0, NULL, NULL);
1502 if(!lpOTM) {
1503 ret = needed;
1504 goto end;
1507 if(needed > cbData) {
1508 ret = 0;
1509 goto end;
1513 lpOTM->otmSize = needed;
1514 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1515 lpOTM->otmFiller = 0;
1516 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1517 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1518 lpOTM->otmfsType = lpOTMW->otmfsType;
1519 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1520 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1521 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1522 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1523 lpOTM->otmAscent = lpOTMW->otmAscent;
1524 lpOTM->otmDescent = lpOTMW->otmDescent;
1525 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1526 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1527 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1528 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1529 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1530 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1531 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1532 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1533 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1534 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1535 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1536 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1537 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1538 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1539 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1540 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1543 ptr = (char*)(lpOTM + 1);
1544 left = needed - sizeof(*lpOTM);
1546 if(lpOTMW->otmpFamilyName) {
1547 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1548 len = WideCharToMultiByte(CP_ACP, 0,
1549 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1550 ptr, left, NULL, NULL);
1551 left -= len;
1552 ptr += len;
1553 } else
1554 lpOTM->otmpFamilyName = 0;
1556 if(lpOTMW->otmpFaceName) {
1557 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1558 len = WideCharToMultiByte(CP_ACP, 0,
1559 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1560 ptr, left, NULL, NULL);
1561 left -= len;
1562 ptr += len;
1563 } else
1564 lpOTM->otmpFaceName = 0;
1566 if(lpOTMW->otmpStyleName) {
1567 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1568 len = WideCharToMultiByte(CP_ACP, 0,
1569 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1570 ptr, left, NULL, NULL);
1571 left -= len;
1572 ptr += len;
1573 } else
1574 lpOTM->otmpStyleName = 0;
1576 if(lpOTMW->otmpFullName) {
1577 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1578 len = WideCharToMultiByte(CP_ACP, 0,
1579 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1580 ptr, left, NULL, NULL);
1581 left -= len;
1582 } else
1583 lpOTM->otmpFullName = 0;
1585 assert(left == 0);
1587 ret = needed;
1589 end:
1590 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1591 HeapFree(GetProcessHeap(), 0, lpOTMW);
1593 return ret;
1597 /***********************************************************************
1598 * GetOutlineTextMetricsW [GDI32.@]
1600 UINT WINAPI GetOutlineTextMetricsW(
1601 HDC hdc, /* [in] Handle of device context */
1602 UINT cbData, /* [in] Size of metric data array */
1603 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1605 DC *dc = DC_GetDCPtr( hdc );
1606 UINT ret;
1608 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1609 if(!dc) return 0;
1611 if(dc->gdiFont)
1612 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1614 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1615 but really this should just be a return 0. */
1617 ret = sizeof(*lpOTM);
1618 if (lpOTM) {
1619 if(cbData < ret)
1620 ret = 0;
1621 else {
1622 memset(lpOTM, 0, ret);
1623 lpOTM->otmSize = sizeof(*lpOTM);
1624 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1626 Further fill of the structure not implemented,
1627 Needs real values for the structure members
1632 GDI_ReleaseObj(hdc);
1633 return ret;
1637 /***********************************************************************
1638 * GetCharWidth (GDI.350)
1640 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1641 LPINT16 buffer )
1643 BOOL retVal = FALSE;
1645 if( firstChar != lastChar )
1647 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1648 sizeof(INT)*(1 + (lastChar - firstChar)));
1649 if( buf32 )
1651 LPINT obuf32 = buf32;
1652 int i;
1654 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1655 if (retVal)
1657 for (i = firstChar; i <= lastChar; i++)
1658 *buffer++ = *buf32++;
1660 HeapFree(GetProcessHeap(), 0, obuf32);
1663 else /* happens quite often to warrant a special treatment */
1665 INT chWidth;
1666 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1667 *buffer = chWidth;
1669 return retVal;
1673 /***********************************************************************
1674 * GetCharWidthW (GDI32.@)
1675 * GetCharWidth32W (GDI32.@)
1677 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1678 LPINT buffer )
1680 UINT i, extra;
1681 BOOL ret = FALSE;
1682 DC * dc = DC_GetDCPtr( hdc );
1683 if (!dc) return FALSE;
1685 if (dc->gdiFont)
1686 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1687 else if (dc->funcs->pGetCharWidth)
1688 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1690 if (ret)
1692 /* convert device units to logical */
1694 extra = dc->vportExtX >> 1;
1695 for( i = firstChar; i <= lastChar; i++, buffer++ )
1696 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1697 ret = TRUE;
1699 GDI_ReleaseObj( hdc );
1700 return ret;
1704 /***********************************************************************
1705 * GetCharWidthA (GDI32.@)
1706 * GetCharWidth32A (GDI32.@)
1708 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1709 LPINT buffer )
1711 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1712 LPSTR str;
1713 LPWSTR wstr;
1714 BOOL ret = TRUE;
1716 if(count <= 0) return FALSE;
1718 str = HeapAlloc(GetProcessHeap(), 0, count);
1719 for(i = 0; i < count; i++)
1720 str[i] = (BYTE)(firstChar + i);
1722 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1724 for(i = 0; i < wlen; i++)
1726 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1728 ret = FALSE;
1729 break;
1731 buffer++;
1734 HeapFree(GetProcessHeap(), 0, str);
1735 HeapFree(GetProcessHeap(), 0, wstr);
1737 return ret;
1741 /* FIXME: all following APIs ******************************************/
1744 /***********************************************************************
1745 * SetMapperFlags (GDI.349)
1747 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1749 return SetMapperFlags( hDC, dwFlag );
1753 /***********************************************************************
1754 * SetMapperFlags (GDI32.@)
1756 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1758 DC *dc = DC_GetDCPtr( hDC );
1759 DWORD ret = 0;
1760 if(!dc) return 0;
1761 if(dc->funcs->pSetMapperFlags)
1762 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1763 else
1764 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1765 GDI_ReleaseObj( hDC );
1766 return ret;
1769 /***********************************************************************
1770 * GetAspectRatioFilterEx (GDI.486)
1772 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1774 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1775 return FALSE;
1778 /***********************************************************************
1779 * GetAspectRatioFilterEx (GDI32.@)
1781 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1783 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1784 return FALSE;
1787 /***********************************************************************
1788 * GetCharABCWidths (GDI.307)
1790 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1791 LPABC16 abc )
1793 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1794 int i;
1796 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1797 HeapFree(GetProcessHeap(),0,abc32);
1798 return FALSE;
1801 for (i=firstChar;i<=lastChar;i++) {
1802 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1803 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1804 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1806 HeapFree(GetProcessHeap(),0,abc32);
1807 return TRUE;
1811 /***********************************************************************
1812 * GetCharABCWidthsA (GDI32.@)
1814 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1815 LPABC abc )
1817 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1818 LPSTR str;
1819 LPWSTR wstr;
1820 BOOL ret = TRUE;
1822 if(count <= 0) return FALSE;
1824 str = HeapAlloc(GetProcessHeap(), 0, count);
1825 for(i = 0; i < count; i++)
1826 str[i] = (BYTE)(firstChar + i);
1828 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1830 for(i = 0; i < wlen; i++)
1832 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1834 ret = FALSE;
1835 break;
1837 abc++;
1840 HeapFree(GetProcessHeap(), 0, str);
1841 HeapFree(GetProcessHeap(), 0, wstr);
1843 return ret;
1847 /******************************************************************************
1848 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1850 * PARAMS
1851 * hdc [I] Handle of device context
1852 * firstChar [I] First character in range to query
1853 * lastChar [I] Last character in range to query
1854 * abc [O] Address of character-width structure
1856 * NOTES
1857 * Only works with TrueType fonts
1859 * RETURNS
1860 * Success: TRUE
1861 * Failure: FALSE
1863 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1864 LPABC abc )
1866 DC *dc = DC_GetDCPtr(hdc);
1867 int i;
1868 GLYPHMETRICS gm;
1869 BOOL ret = FALSE;
1871 if(dc->gdiFont) {
1872 for (i=firstChar;i<=lastChar;i++) {
1873 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1874 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1875 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1876 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1878 ret = TRUE;
1880 GDI_ReleaseObj(hdc);
1881 return ret;
1885 /***********************************************************************
1886 * GetGlyphOutline (GDI.309)
1888 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1889 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1890 LPVOID lpBuffer, const MAT2 *lpmat2 )
1892 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1893 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1894 return (DWORD)-1; /* failure */
1898 /***********************************************************************
1899 * GetGlyphOutlineA (GDI32.@)
1901 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1902 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1903 LPVOID lpBuffer, const MAT2 *lpmat2 )
1905 LPWSTR p = NULL;
1906 DWORD ret;
1907 UINT c;
1909 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1910 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1911 c = p[0];
1912 } else
1913 c = uChar;
1914 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1915 lpmat2);
1916 if(p)
1917 HeapFree(GetProcessHeap(), 0, p);
1918 return ret;
1921 /***********************************************************************
1922 * GetGlyphOutlineW (GDI32.@)
1924 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1925 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1926 LPVOID lpBuffer, const MAT2 *lpmat2 )
1928 DC *dc = DC_GetDCPtr(hdc);
1929 DWORD ret;
1931 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1932 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1934 if(!dc) return GDI_ERROR;
1936 if(dc->gdiFont)
1937 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1938 cbBuffer, lpBuffer, lpmat2);
1939 else
1940 ret = GDI_ERROR;
1942 GDI_ReleaseObj(hdc);
1943 return ret;
1946 /***********************************************************************
1947 * CreateScalableFontResource (GDI.310)
1949 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1950 LPCSTR lpszResourceFile,
1951 LPCSTR fontFile, LPCSTR path )
1953 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1954 fontFile, path );
1957 /***********************************************************************
1958 * CreateScalableFontResourceA (GDI32.@)
1960 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1961 LPCSTR lpszResourceFile,
1962 LPCSTR lpszFontFile,
1963 LPCSTR lpszCurrentPath )
1965 /* fHidden=1 - only visible for the calling app, read-only, not
1966 * enumbered with EnumFonts/EnumFontFamilies
1967 * lpszCurrentPath can be NULL
1969 FIXME("(%ld,%s,%s,%s): stub\n",
1970 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1971 debugstr_a(lpszCurrentPath) );
1972 return FALSE; /* create failed */
1975 /***********************************************************************
1976 * CreateScalableFontResourceW (GDI32.@)
1978 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1979 LPCWSTR lpszResourceFile,
1980 LPCWSTR lpszFontFile,
1981 LPCWSTR lpszCurrentPath )
1983 FIXME("(%ld,%p,%p,%p): stub\n",
1984 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1985 return FALSE; /* create failed */
1989 /*************************************************************************
1990 * GetRasterizerCaps (GDI.313)
1992 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1994 return GetRasterizerCaps( lprs, cbNumBytes );
1998 /*************************************************************************
1999 * GetRasterizerCaps (GDI32.@)
2001 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
2003 lprs->nSize = sizeof(RASTERIZER_STATUS);
2004 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
2005 lprs->nLanguageID = 0;
2006 return TRUE;
2010 /*************************************************************************
2011 * GetKerningPairs (GDI.332)
2014 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
2015 LPKERNINGPAIR16 lpKerningPairs )
2017 /* At this time kerning is ignored (set to 0) */
2018 int i;
2019 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2020 if (lpKerningPairs)
2021 for (i = 0; i < cPairs; i++)
2022 lpKerningPairs[i].iKernAmount = 0;
2023 /* FIXME: Should this function call SetLastError (0)? This is yet another
2024 * Microsoft function that can return 0 on success or failure
2026 return 0;
2031 /*************************************************************************
2032 * GetKerningPairsA (GDI32.@)
2034 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2035 LPKERNINGPAIR lpKerningPairs )
2037 int i;
2038 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2039 for (i = 0; i < cPairs; i++)
2040 lpKerningPairs[i].iKernAmount = 0;
2041 return 0;
2045 /*************************************************************************
2046 * GetKerningPairsW (GDI32.@)
2048 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2049 LPKERNINGPAIR lpKerningPairs )
2051 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
2054 /*************************************************************************
2055 * TranslateCharsetInfo [GDI32.@]
2056 * TranslateCharsetInfo [USER32.@]
2058 * Fills a CHARSETINFO structure for a character set, code page, or
2059 * font. This allows making the correspondance between different labelings
2060 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2061 * of the same encoding.
2063 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2064 * only one codepage should be set in *lpSrc.
2066 * RETURNS
2067 * TRUE on success, FALSE on failure.
2070 BOOL WINAPI TranslateCharsetInfo(
2071 LPDWORD lpSrc, /* [in]
2072 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2073 if flags == TCI_SRCCHARSET: a character set value
2074 if flags == TCI_SRCCODEPAGE: a code page value
2076 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2077 DWORD flags /* [in] determines interpretation of lpSrc */
2079 int index = 0;
2080 switch (flags) {
2081 case TCI_SRCFONTSIG:
2082 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2083 break;
2084 case TCI_SRCCODEPAGE:
2085 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2086 break;
2087 case TCI_SRCCHARSET:
2088 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2089 break;
2090 default:
2091 return FALSE;
2093 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2094 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2095 return TRUE;
2098 /*************************************************************************
2099 * GetFontLanguageInfo (GDI32.@)
2101 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
2102 /* return value 0 is correct for most cases anyway */
2103 FIXME("(%x):stub!\n", hdc);
2104 return 0;
2107 /*************************************************************************
2108 * GetFontLanguageInfo (GDI.616)
2110 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
2111 /* return value 0 is correct for most cases anyway */
2112 FIXME("(%x):stub!\n",hdc);
2113 return 0;
2116 /*************************************************************************
2117 * GetFontData [GDI32.@] Retrieve data for TrueType font
2119 * RETURNS
2121 * success: Number of bytes returned
2122 * failure: GDI_ERROR
2124 * NOTES
2126 * Calls SetLastError()
2129 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2130 LPVOID buffer, DWORD length)
2132 DC *dc = DC_GetDCPtr(hdc);
2133 DWORD ret = GDI_ERROR;
2135 if(!dc) return GDI_ERROR;
2137 if(dc->gdiFont)
2138 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2140 GDI_ReleaseObj(hdc);
2141 return ret;
2144 /*************************************************************************
2145 * GetFontData [GDI.311]
2148 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2149 LPVOID lpvBuffer, DWORD cbData)
2151 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2154 /*************************************************************************
2155 * GetGlyphIndicesA [GDI32.@]
2157 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2158 LPWORD pgi, DWORD flags)
2160 DWORD ret;
2161 WCHAR *lpstrW;
2162 INT countW;
2164 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2165 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2167 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2168 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2169 HeapFree(GetProcessHeap(), 0, lpstrW);
2171 return ret;
2174 /*************************************************************************
2175 * GetGlyphIndicesW [GDI32.@]
2177 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2178 LPWORD pgi, DWORD flags)
2180 DC *dc = DC_GetDCPtr(hdc);
2181 DWORD ret = GDI_ERROR;
2183 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2184 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2186 if(!dc) return GDI_ERROR;
2188 if(dc->gdiFont)
2189 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2191 GDI_ReleaseObj(hdc);
2192 return ret;
2195 /*************************************************************************
2196 * GetCharacterPlacementA [GDI32.@]
2198 * NOTES:
2199 * the web browser control of ie4 calls this with dwFlags=0
2201 DWORD WINAPI
2202 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2203 INT nMaxExtent, GCP_RESULTSA *lpResults,
2204 DWORD dwFlags)
2206 WCHAR *lpStringW;
2207 INT uCountW;
2208 GCP_RESULTSW resultsW;
2209 DWORD ret;
2210 UINT font_cp;
2212 TRACE("%s, %d, %d, 0x%08lx\n",
2213 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2215 /* both structs are equal in size */
2216 memcpy(&resultsW, lpResults, sizeof(resultsW));
2218 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2219 if(lpResults->lpOutString)
2220 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2221 else
2222 resultsW.lpOutString = NULL;
2224 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2226 if(lpResults->lpOutString)
2227 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2228 lpResults->lpOutString, uCount, NULL, NULL );
2230 HeapFree(GetProcessHeap(), 0, lpStringW);
2231 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2233 return ret;
2236 /*************************************************************************
2237 * GetCharacterPlacementW [GDI32.@]
2239 DWORD WINAPI
2240 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
2241 INT nMaxExtent, GCP_RESULTSW *lpResults,
2242 DWORD dwFlags)
2244 DWORD ret=0;
2245 SIZE size;
2246 UINT i, nSet;
2248 TRACE("%s, %d, %d, 0x%08lx\n",
2249 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2251 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2252 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2253 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2254 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2255 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2257 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
2258 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2259 if(lpResults->lpClass) FIXME("classes not implemented\n");
2261 /* FIXME: reordering not implemented */
2262 /* copy will do if the GCP_REORDER flag is not set */
2263 if(lpResults->lpOutString)
2264 lstrcpynW(lpResults->lpOutString, lpString, uCount);
2266 nSet = (UINT)uCount;
2267 if(nSet > lpResults->nGlyphs)
2268 nSet = lpResults->nGlyphs;
2270 /* return number of initialized fields */
2271 lpResults->nGlyphs = nSet;
2273 if(lpResults->lpOrder)
2275 for(i = 0; i < nSet; i++)
2276 lpResults->lpOrder[i] = i;
2279 if (lpResults->lpDx)
2281 int c;
2282 for (i = 0; i < nSet; i++)
2284 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2285 lpResults->lpDx[i]= c;
2289 if(lpResults->lpGlyphs)
2290 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2292 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2293 ret = MAKELONG(size.cx, size.cy);
2295 return ret;
2298 /*************************************************************************
2299 * GetCharABCWidthsFloatA [GDI32.@]
2301 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2302 LPABCFLOAT lpABCF)
2304 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2305 return 0;
2308 /*************************************************************************
2309 * GetCharABCWidthsFloatW [GDI32.@]
2311 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2312 UINT iLastChar, LPABCFLOAT lpABCF)
2314 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2315 return 0;
2318 /*************************************************************************
2319 * GetCharWidthFloatA [GDI32.@]
2321 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2322 UINT iLastChar, PFLOAT pxBuffer)
2324 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2325 return 0;
2328 /*************************************************************************
2329 * GetCharWidthFloatW [GDI32.@]
2331 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2332 UINT iLastChar, PFLOAT pxBuffer)
2334 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2335 return 0;
2339 /***********************************************************************
2341 * Font Resource API *
2343 ***********************************************************************/
2344 /***********************************************************************
2345 * AddFontResource (GDI.119)
2347 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2349 * FIXME: Load header and find the best-matching font in the fontList;
2350 * fixup dfPoints if all metrics are identical, otherwise create
2351 * new fontAlias. When soft font support is ready this will
2352 * simply create a new fontResource ('filename' will go into
2353 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
2354 * flag set.
2356 INT16 WINAPI AddFontResource16( LPCSTR filename )
2358 return AddFontResourceA( filename );
2362 /***********************************************************************
2363 * AddFontResourceA (GDI32.@)
2365 INT WINAPI AddFontResourceA( LPCSTR str )
2367 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2368 "this font manually.\n", debugstr_a(str));
2369 return 1;
2373 /***********************************************************************
2374 * AddFontResourceW (GDI32.@)
2376 INT WINAPI AddFontResourceW( LPCWSTR str )
2378 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2379 "this font manually.\n", debugstr_w(str));
2380 return 1;
2383 /***********************************************************************
2384 * RemoveFontResource (GDI.136)
2386 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2388 FIXME("(%s): stub\n", debugstr_a(str));
2389 return TRUE;
2393 /***********************************************************************
2394 * RemoveFontResourceA (GDI32.@)
2396 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2398 /* This is how it should look like */
2400 fontResource** ppfr;
2401 BOOL32 retVal = FALSE;
2403 EnterCriticalSection( &crtsc_fonts_X11 );
2404 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2405 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2407 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2408 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2410 if( (*ppfr)->fo_count )
2411 (*ppfr)->fr_flags |= FR_REMOVED;
2412 else
2413 XFONT_RemoveFontResource( ppfr );
2415 retVal = TRUE;
2417 LeaveCriticalSection( &crtsc_fonts_X11 );
2418 return retVal;
2420 FIXME("(%s): stub\n", debugstr_a(str));
2421 return TRUE;
2425 /***********************************************************************
2426 * RemoveFontResourceW (GDI32.@)
2428 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2430 FIXME("(%s): stub\n", debugstr_w(str) );
2431 return TRUE;