Added function table to GDI objects for better encapsulation.
[wine.git] / objects / font.c
blobe26bdaae0eb7924cda80840609017ef090215375
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 LPLOGFONT16 lpLogFontParam;
57 FONTENUMPROCEX16 lpEnumFunc;
58 LPARAM lpData;
60 LPNEWTEXTMETRICEX16 lpTextMetric;
61 LPENUMLOGFONTEX16 lpLogFont;
62 SEGPTR segTextMetric;
63 SEGPTR segLogFont;
64 HDC hdc;
65 DC *dc;
66 PHYSDEV physDev;
67 } fontEnum16;
69 typedef struct
71 LPLOGFONTW lpLogFontParam;
72 FONTENUMPROCEXW lpEnumFunc;
73 LPARAM lpData;
74 DWORD dwFlags;
75 HDC hdc;
76 DC *dc;
77 PHYSDEV physDev;
78 } fontEnum32;
81 * For TranslateCharsetInfo
83 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
84 #define MAXTCIINDEX 32
85 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
86 /* ANSI */
87 { ANSI_CHARSET, 1252, FS(0)},
88 { EASTEUROPE_CHARSET, 1250, FS(1)},
89 { RUSSIAN_CHARSET, 1251, FS(2)},
90 { GREEK_CHARSET, 1253, FS(3)},
91 { TURKISH_CHARSET, 1254, FS(4)},
92 { HEBREW_CHARSET, 1255, FS(5)},
93 { ARABIC_CHARSET, 1256, FS(6)},
94 { BALTIC_CHARSET, 1257, FS(7)},
95 /* reserved by ANSI */
96 { DEFAULT_CHARSET, 0, FS(0)},
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 /* ANSI and OEM */
105 { THAI_CHARSET, 874, FS(16)},
106 { SHIFTJIS_CHARSET, 932, FS(17)},
107 { GB2312_CHARSET, 936, FS(18)},
108 { HANGEUL_CHARSET, 949, FS(19)},
109 { CHINESEBIG5_CHARSET, 950, FS(20)},
110 { JOHAB_CHARSET, 1361, FS(21)},
111 /* reserved for alternate ANSI and OEM */
112 { DEFAULT_CHARSET, 0, FS(0)},
113 { DEFAULT_CHARSET, 0, FS(0)},
114 { DEFAULT_CHARSET, 0, FS(0)},
115 { DEFAULT_CHARSET, 0, FS(0)},
116 { DEFAULT_CHARSET, 0, FS(0)},
117 { DEFAULT_CHARSET, 0, FS(0)},
118 { DEFAULT_CHARSET, 0, FS(0)},
119 { DEFAULT_CHARSET, 0, FS(0)},
120 /* reserved for system */
121 { DEFAULT_CHARSET, 0, FS(0)},
122 { DEFAULT_CHARSET, 0, FS(0)},
125 /* ### start build ### */
126 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
127 /* ### stop build ### */
129 /***********************************************************************
130 * LOGFONT conversion functions.
132 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
134 font16->lfHeight = font32->lfHeight;
135 font16->lfWidth = font32->lfWidth;
136 font16->lfEscapement = font32->lfEscapement;
137 font16->lfOrientation = font32->lfOrientation;
138 font16->lfWeight = font32->lfWeight;
139 font16->lfItalic = font32->lfItalic;
140 font16->lfUnderline = font32->lfUnderline;
141 font16->lfStrikeOut = font32->lfStrikeOut;
142 font16->lfCharSet = font32->lfCharSet;
143 font16->lfOutPrecision = font32->lfOutPrecision;
144 font16->lfClipPrecision = font32->lfClipPrecision;
145 font16->lfQuality = font32->lfQuality;
146 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
147 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
150 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
152 font16->lfHeight = font32->lfHeight;
153 font16->lfWidth = font32->lfWidth;
154 font16->lfEscapement = font32->lfEscapement;
155 font16->lfOrientation = font32->lfOrientation;
156 font16->lfWeight = font32->lfWeight;
157 font16->lfItalic = font32->lfItalic;
158 font16->lfUnderline = font32->lfUnderline;
159 font16->lfStrikeOut = font32->lfStrikeOut;
160 font16->lfCharSet = font32->lfCharSet;
161 font16->lfOutPrecision = font32->lfOutPrecision;
162 font16->lfClipPrecision = font32->lfClipPrecision;
163 font16->lfQuality = font32->lfQuality;
164 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
165 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
166 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
167 font16->lfFaceName[LF_FACESIZE-1] = 0;
170 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
172 font32->lfHeight = font16->lfHeight;
173 font32->lfWidth = font16->lfWidth;
174 font32->lfEscapement = font16->lfEscapement;
175 font32->lfOrientation = font16->lfOrientation;
176 font32->lfWeight = font16->lfWeight;
177 font32->lfItalic = font16->lfItalic;
178 font32->lfUnderline = font16->lfUnderline;
179 font32->lfStrikeOut = font16->lfStrikeOut;
180 font32->lfCharSet = font16->lfCharSet;
181 font32->lfOutPrecision = font16->lfOutPrecision;
182 font32->lfClipPrecision = font16->lfClipPrecision;
183 font32->lfQuality = font16->lfQuality;
184 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
185 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
188 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
190 font32->lfHeight = font16->lfHeight;
191 font32->lfWidth = font16->lfWidth;
192 font32->lfEscapement = font16->lfEscapement;
193 font32->lfOrientation = font16->lfOrientation;
194 font32->lfWeight = font16->lfWeight;
195 font32->lfItalic = font16->lfItalic;
196 font32->lfUnderline = font16->lfUnderline;
197 font32->lfStrikeOut = font16->lfStrikeOut;
198 font32->lfCharSet = font16->lfCharSet;
199 font32->lfOutPrecision = font16->lfOutPrecision;
200 font32->lfClipPrecision = font16->lfClipPrecision;
201 font32->lfQuality = font16->lfQuality;
202 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
203 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
204 font32->lfFaceName[LF_FACESIZE-1] = 0;
207 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
209 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
210 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
211 LF_FACESIZE);
214 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
216 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
217 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
218 LF_FACESIZE, NULL, NULL);
221 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
223 FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
224 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
225 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
226 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
229 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
231 FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
233 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
234 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
235 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
236 font32->elfStyle[LF_FACESIZE-1] = 0;
237 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
238 font32->elfScript[LF_FACESIZE-1] = 0;
241 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
243 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
245 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
246 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
247 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
248 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
249 font16->elfStyle, LF_FACESIZE, NULL, NULL );
250 font16->elfStyle[LF_FACESIZE-1] = '\0';
251 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
252 font16->elfScript, LF_FACESIZE, NULL, NULL );
253 font16->elfScript[LF_FACESIZE-1] = '\0';
256 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
258 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
260 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
261 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
262 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
263 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
264 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
265 fontA->elfStyle[LF_FACESIZE-1] = '\0';
266 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
267 fontA->elfScript, LF_FACESIZE, NULL, NULL );
268 fontA->elfScript[LF_FACESIZE-1] = '\0';
271 /***********************************************************************
272 * TEXTMETRIC conversion functions.
274 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
276 ptm16->tmHeight = ptm32->tmHeight;
277 ptm16->tmAscent = ptm32->tmAscent;
278 ptm16->tmDescent = ptm32->tmDescent;
279 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
280 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
281 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
282 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
283 ptm16->tmWeight = ptm32->tmWeight;
284 ptm16->tmOverhang = ptm32->tmOverhang;
285 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
286 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
287 ptm16->tmFirstChar = ptm32->tmFirstChar;
288 ptm16->tmLastChar = ptm32->tmLastChar;
289 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
290 ptm16->tmBreakChar = ptm32->tmBreakChar;
291 ptm16->tmItalic = ptm32->tmItalic;
292 ptm16->tmUnderlined = ptm32->tmUnderlined;
293 ptm16->tmStruckOut = ptm32->tmStruckOut;
294 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
295 ptm16->tmCharSet = ptm32->tmCharSet;
298 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
300 ptm16->tmHeight = ptm32->tmHeight;
301 ptm16->tmAscent = ptm32->tmAscent;
302 ptm16->tmDescent = ptm32->tmDescent;
303 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
304 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
305 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
306 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
307 ptm16->tmWeight = ptm32->tmWeight;
308 ptm16->tmOverhang = ptm32->tmOverhang;
309 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
310 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
311 ptm16->tmFirstChar = ptm32->tmFirstChar;
312 ptm16->tmLastChar = ptm32->tmLastChar;
313 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
314 ptm16->tmBreakChar = ptm32->tmBreakChar;
315 ptm16->tmItalic = ptm32->tmItalic;
316 ptm16->tmUnderlined = ptm32->tmUnderlined;
317 ptm16->tmStruckOut = ptm32->tmStruckOut;
318 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
319 ptm16->tmCharSet = ptm32->tmCharSet;
322 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
324 ptm32->tmHeight = ptm16->tmHeight;
325 ptm32->tmAscent = ptm16->tmAscent;
326 ptm32->tmDescent = ptm16->tmDescent;
327 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
328 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
329 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
330 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
331 ptm32->tmWeight = ptm16->tmWeight;
332 ptm32->tmOverhang = ptm16->tmOverhang;
333 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
334 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
335 ptm32->tmFirstChar = ptm16->tmFirstChar;
336 ptm32->tmLastChar = ptm16->tmLastChar;
337 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
338 ptm32->tmBreakChar = ptm16->tmBreakChar;
339 ptm32->tmItalic = ptm16->tmItalic;
340 ptm32->tmUnderlined = ptm16->tmUnderlined;
341 ptm32->tmStruckOut = ptm16->tmStruckOut;
342 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
343 ptm32->tmCharSet = ptm16->tmCharSet;
346 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
348 ptm32->tmHeight = ptm16->tmHeight;
349 ptm32->tmAscent = ptm16->tmAscent;
350 ptm32->tmDescent = ptm16->tmDescent;
351 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
352 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
353 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
354 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
355 ptm32->tmWeight = ptm16->tmWeight;
356 ptm32->tmOverhang = ptm16->tmOverhang;
357 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
358 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
359 ptm32->tmFirstChar = ptm16->tmFirstChar;
360 ptm32->tmLastChar = ptm16->tmLastChar;
361 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
362 ptm32->tmBreakChar = ptm16->tmBreakChar;
363 ptm32->tmItalic = ptm16->tmItalic;
364 ptm32->tmUnderlined = ptm16->tmUnderlined;
365 ptm32->tmStruckOut = ptm16->tmStruckOut;
366 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
367 ptm32->tmCharSet = ptm16->tmCharSet;
370 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
372 ptm32W->tmHeight = ptm32A->tmHeight;
373 ptm32W->tmAscent = ptm32A->tmAscent;
374 ptm32W->tmDescent = ptm32A->tmDescent;
375 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
376 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
377 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
378 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
379 ptm32W->tmWeight = ptm32A->tmWeight;
380 ptm32W->tmOverhang = ptm32A->tmOverhang;
381 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
382 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
383 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
384 ptm32W->tmLastChar = ptm32A->tmLastChar;
385 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
386 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
387 ptm32W->tmItalic = ptm32A->tmItalic;
388 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
389 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
390 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
391 ptm32W->tmCharSet = ptm32A->tmCharSet;
394 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
396 ptmA->tmHeight = ptmW->tmHeight;
397 ptmA->tmAscent = ptmW->tmAscent;
398 ptmA->tmDescent = ptmW->tmDescent;
399 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
400 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
401 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
402 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
403 ptmA->tmWeight = ptmW->tmWeight;
404 ptmA->tmOverhang = ptmW->tmOverhang;
405 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
406 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
407 ptmA->tmFirstChar = ptmW->tmFirstChar;
408 ptmA->tmLastChar = ptmW->tmLastChar;
409 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
410 ptmA->tmBreakChar = ptmW->tmBreakChar;
411 ptmA->tmItalic = ptmW->tmItalic;
412 ptmA->tmUnderlined = ptmW->tmUnderlined;
413 ptmA->tmStruckOut = ptmW->tmStruckOut;
414 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
415 ptmA->tmCharSet = ptmW->tmCharSet;
419 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
421 FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
422 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
423 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
424 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
425 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
426 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
429 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
431 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
432 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
433 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
434 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
435 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
436 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
439 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
441 FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
442 ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
443 ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
444 ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
445 ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
446 memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
450 /***********************************************************************
451 * CreateFontIndirect (GDI.57)
453 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
455 LOGFONTW lfW;
457 if(plf16) {
458 FONT_LogFont16ToW( plf16, &lfW );
459 return CreateFontIndirectW( &lfW );
460 } else {
461 return CreateFontIndirectW( NULL );
466 /***********************************************************************
467 * CreateFontIndirectA (GDI32.@)
469 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
471 LOGFONTW lfW;
473 if (plfA) {
474 FONT_LogFontAToW( plfA, &lfW );
475 return CreateFontIndirectW( &lfW );
476 } else
477 return CreateFontIndirectW( NULL );
481 /***********************************************************************
482 * CreateFontIndirectW (GDI32.@)
484 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
486 HFONT hFont = 0;
488 if (plf)
490 FONTOBJ* fontPtr;
491 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
493 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
495 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
496 plf->lfHeight, plf->lfWidth,
497 plf->lfEscapement, plf->lfOrientation,
498 plf->lfPitchAndFamily,
499 debugstr_w(plf->lfFaceName),
500 plf->lfWeight > 400 ? "Bold" : "",
501 plf->lfItalic ? "Italic" : "", hFont);
503 if (plf->lfEscapement != plf->lfOrientation) {
504 /* this should really depend on whether GM_ADVANCED is set */
505 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
506 WARN("orientation angle %f set to "
507 "escapement angle %f for new font %04x\n",
508 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
510 GDI_ReleaseObj( hFont );
513 else WARN("(NULL) => NULL\n");
515 return hFont;
518 /***********************************************************************
519 * CreateFont (GDI.56)
521 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
522 INT16 weight, BYTE italic, BYTE underline,
523 BYTE strikeout, BYTE charset, BYTE outpres,
524 BYTE clippres, BYTE quality, BYTE pitch,
525 LPCSTR name )
527 LOGFONT16 logfont;
529 logfont.lfHeight = height;
530 logfont.lfWidth = width;
531 logfont.lfEscapement = esc;
532 logfont.lfOrientation = orient;
533 logfont.lfWeight = weight;
534 logfont.lfItalic = italic;
535 logfont.lfUnderline = underline;
536 logfont.lfStrikeOut = strikeout;
537 logfont.lfCharSet = charset;
538 logfont.lfOutPrecision = outpres;
539 logfont.lfClipPrecision = clippres;
540 logfont.lfQuality = quality;
541 logfont.lfPitchAndFamily = pitch;
543 if (name)
544 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
545 else
546 logfont.lfFaceName[0] = '\0';
548 return CreateFontIndirect16( &logfont );
551 /*************************************************************************
552 * CreateFontA (GDI32.@)
554 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
555 INT orient, INT weight, DWORD italic,
556 DWORD underline, DWORD strikeout, DWORD charset,
557 DWORD outpres, DWORD clippres, DWORD quality,
558 DWORD pitch, LPCSTR name )
560 LOGFONTA logfont;
562 logfont.lfHeight = height;
563 logfont.lfWidth = width;
564 logfont.lfEscapement = esc;
565 logfont.lfOrientation = orient;
566 logfont.lfWeight = weight;
567 logfont.lfItalic = italic;
568 logfont.lfUnderline = underline;
569 logfont.lfStrikeOut = strikeout;
570 logfont.lfCharSet = charset;
571 logfont.lfOutPrecision = outpres;
572 logfont.lfClipPrecision = clippres;
573 logfont.lfQuality = quality;
574 logfont.lfPitchAndFamily = pitch;
576 if (name)
577 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
578 else
579 logfont.lfFaceName[0] = '\0';
581 return CreateFontIndirectA( &logfont );
584 /*************************************************************************
585 * CreateFontW (GDI32.@)
587 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
588 INT orient, INT weight, DWORD italic,
589 DWORD underline, DWORD strikeout, DWORD charset,
590 DWORD outpres, DWORD clippres, DWORD quality,
591 DWORD pitch, LPCWSTR name )
593 LOGFONTW logfont;
595 logfont.lfHeight = height;
596 logfont.lfWidth = width;
597 logfont.lfEscapement = esc;
598 logfont.lfOrientation = orient;
599 logfont.lfWeight = weight;
600 logfont.lfItalic = italic;
601 logfont.lfUnderline = underline;
602 logfont.lfStrikeOut = strikeout;
603 logfont.lfCharSet = charset;
604 logfont.lfOutPrecision = outpres;
605 logfont.lfClipPrecision = clippres;
606 logfont.lfQuality = quality;
607 logfont.lfPitchAndFamily = pitch;
609 if (name)
610 lstrcpynW(logfont.lfFaceName, name,
611 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
612 else
613 logfont.lfFaceName[0] = '\0';
615 return CreateFontIndirectW( &logfont );
619 /***********************************************************************
620 * FONT_SelectObject
622 * If the driver supports vector fonts we create a gdi font first and
623 * then call the driver to give it a chance to supply its own device
624 * font. If the driver wants to do this it returns TRUE and we can
625 * delete the gdi font, if the driver wants to use the gdi font it
626 * should return FALSE, to signal an error return GDI_ERROR. For
627 * drivers that don't support vector fonts they must supply their own
628 * font.
630 static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
632 HGDIOBJ ret = 0;
633 DC *dc = DC_GetDCPtr( hdc );
635 if (!dc) return 0;
637 if (dc->hFont != handle || dc->gdiFont == NULL)
639 if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
640 dc->gdiFont = WineEngCreateFontInstance(dc, handle);
643 if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
645 if (ret && dc->gdiFont) dc->gdiFont = 0;
647 if (ret == GDI_ERROR)
648 ret = 0; /* SelectObject returns 0 on error */
649 else
651 ret = dc->hFont;
652 dc->hFont = handle;
654 GDI_ReleaseObj( hdc );
655 return ret;
659 /***********************************************************************
660 * FONT_GetObject16
662 static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
664 FONTOBJ *font = obj;
665 LOGFONT16 lf16;
667 FONT_LogFontWTo16( &font->logfont, &lf16 );
669 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
670 memcpy( buffer, &lf16, count );
671 return count;
674 /***********************************************************************
675 * FONT_GetObjectA
677 static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
679 FONTOBJ *font = obj;
680 LOGFONTA lfA;
682 FONT_LogFontWToA( &font->logfont, &lfA );
684 if (count > sizeof(lfA)) count = sizeof(lfA);
685 memcpy( buffer, &lfA, count );
686 return count;
689 /***********************************************************************
690 * FONT_GetObjectW
692 static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
694 FONTOBJ *font = obj;
695 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
696 memcpy( buffer, &font->logfont, count );
697 return count;
701 /***********************************************************************
702 * FONT_DeleteObject
704 static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
706 WineEngDestroyFontInstance( handle );
707 return GDI_FreeObject( handle, obj );
711 /***********************************************************************
712 * FONT_EnumInstance16
714 * Called by the device driver layer to pass font info
715 * down to the application.
717 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
718 DWORD fType, LPARAM lp )
720 fontEnum16 *pfe = (fontEnum16*)lp;
721 INT ret = 1;
722 DC *dc;
724 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
725 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
727 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
728 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
729 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
731 ret = FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
732 (UINT16)fType, (LPARAM)pfe->lpData );
733 /* get the lock again and make sure the DC is still valid */
734 dc = DC_GetDCPtr( pfe->hdc );
735 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
737 if (dc) GDI_ReleaseObj( pfe->hdc );
738 pfe->hdc = 0; /* make sure we don't try to release it later on */
739 ret = 0;
742 return ret;
745 /***********************************************************************
746 * FONT_EnumInstance
748 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
749 DWORD fType, LPARAM lp )
751 fontEnum32 *pfe = (fontEnum32*)lp;
752 INT ret = 1;
753 DC *dc;
755 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
756 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
757 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
759 /* convert font metrics */
760 ENUMLOGFONTEXA logfont;
761 NEWTEXTMETRICEXA tmA;
763 pfe->dwFlags |= ENUM_CALLED;
764 if (!(pfe->dwFlags & ENUM_UNICODE))
766 FONT_EnumLogFontExWToA( plf, &logfont);
767 FONT_NewTextMetricExWToA( ptm, &tmA );
768 plf = (LPENUMLOGFONTEXW)&logfont;
769 ptm = (LPNEWTEXTMETRICEXW)&tmA;
771 GDI_ReleaseObj( pfe->hdc ); /* release the GDI lock */
773 ret = pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
775 /* get the lock again and make sure the DC is still valid */
776 dc = DC_GetDCPtr( pfe->hdc );
777 if (!dc || dc != pfe->dc || dc->physDev != pfe->physDev)
779 if (dc) GDI_ReleaseObj( pfe->hdc );
780 pfe->hdc = 0; /* make sure we don't try to release it later on */
781 ret = 0;
784 return ret;
787 /***********************************************************************
788 * EnumFontFamiliesEx (GDI.613)
790 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
791 FONTENUMPROCEX16 efproc, LPARAM lParam,
792 DWORD dwFlags)
794 fontEnum16 fe16;
795 INT16 retVal = 0;
796 DC* dc = DC_GetDCPtr( hDC );
798 if (!dc) return 0;
799 fe16.hdc = hDC;
800 fe16.dc = dc;
801 fe16.physDev = dc->physDev;
803 if (dc->funcs->pEnumDeviceFonts)
805 NEWTEXTMETRICEX16 tm16;
806 ENUMLOGFONTEX16 lf16;
807 LOGFONTW lfW;
808 FONT_LogFont16ToW(plf, &lfW);
810 fe16.lpLogFontParam = plf;
811 fe16.lpEnumFunc = efproc;
812 fe16.lpData = lParam;
813 fe16.lpTextMetric = &tm16;
814 fe16.lpLogFont = &lf16;
815 fe16.segTextMetric = MapLS( &tm16 );
816 fe16.segLogFont = MapLS( &lf16 );
818 retVal = dc->funcs->pEnumDeviceFonts( dc->physDev, &lfW,
819 FONT_EnumInstance16, (LPARAM)&fe16 );
820 UnMapLS( fe16.segTextMetric );
821 UnMapLS( fe16.segLogFont );
823 if (fe16.hdc) GDI_ReleaseObj( fe16.hdc );
824 return retVal;
827 /***********************************************************************
828 * FONT_EnumFontFamiliesEx
830 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
831 FONTENUMPROCEXW efproc,
832 LPARAM lParam, DWORD dwUnicode)
834 INT ret = 1, ret2;
835 DC *dc = DC_GetDCPtr( hDC );
836 fontEnum32 fe32;
837 BOOL enum_gdi_fonts;
839 if (!dc) return 0;
841 TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
842 plf->lfCharSet);
843 fe32.lpLogFontParam = plf;
844 fe32.lpEnumFunc = efproc;
845 fe32.lpData = lParam;
846 fe32.dwFlags = dwUnicode;
847 fe32.hdc = hDC;
848 fe32.dc = dc;
849 fe32.physDev = dc->physDev;
851 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
853 if (!dc->funcs->pEnumDeviceFonts && !enum_gdi_fonts)
855 ret = 0;
856 goto done;
859 if (enum_gdi_fonts)
860 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
861 fe32.dwFlags &= ~ENUM_CALLED;
862 if (ret && dc->funcs->pEnumDeviceFonts) {
863 ret2 = dc->funcs->pEnumDeviceFonts( dc->physDev, plf, FONT_EnumInstance, (LPARAM)&fe32 );
864 if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
865 ret = ret2;
867 done:
868 if (fe32.hdc) GDI_ReleaseObj( fe32.hdc );
869 return ret;
872 /***********************************************************************
873 * EnumFontFamiliesExW (GDI32.@)
875 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
876 FONTENUMPROCEXW efproc,
877 LPARAM lParam, DWORD dwFlags )
879 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
882 /***********************************************************************
883 * EnumFontFamiliesExA (GDI32.@)
885 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
886 FONTENUMPROCEXA efproc,
887 LPARAM lParam, DWORD dwFlags)
889 LOGFONTW lfW;
890 FONT_LogFontAToW( plf, &lfW );
892 return FONT_EnumFontFamiliesEx( hDC, &lfW,
893 (FONTENUMPROCEXW)efproc, lParam, 0);
896 /***********************************************************************
897 * EnumFontFamilies (GDI.330)
899 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
900 FONTENUMPROC16 efproc, LPARAM lpData )
902 LOGFONT16 lf;
904 lf.lfCharSet = DEFAULT_CHARSET;
905 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
906 else lf.lfFaceName[0] = '\0';
908 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
911 /***********************************************************************
912 * EnumFontFamiliesA (GDI32.@)
914 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
915 FONTENUMPROCA efproc, LPARAM lpData )
917 LOGFONTA lf;
919 lf.lfCharSet = DEFAULT_CHARSET;
920 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
921 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
923 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
926 /***********************************************************************
927 * EnumFontFamiliesW (GDI32.@)
929 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
930 FONTENUMPROCW efproc, LPARAM lpData )
932 LOGFONTW lf;
934 lf.lfCharSet = DEFAULT_CHARSET;
935 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
936 else lf.lfFaceName[0] = 0;
938 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
941 /***********************************************************************
942 * EnumFonts (GDI.70)
944 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
945 LPARAM lpData )
947 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
950 /***********************************************************************
951 * EnumFontsA (GDI32.@)
953 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
954 LPARAM lpData )
956 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
959 /***********************************************************************
960 * EnumFontsW (GDI32.@)
962 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
963 LPARAM lpData )
965 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
969 /***********************************************************************
970 * GetTextCharacterExtra (GDI.89)
972 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
974 return (INT16)GetTextCharacterExtra( hdc );
978 /***********************************************************************
979 * GetTextCharacterExtra (GDI32.@)
981 INT WINAPI GetTextCharacterExtra( HDC hdc )
983 INT ret;
984 DC *dc = DC_GetDCPtr( hdc );
985 if (!dc) return 0;
986 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
987 / dc->vportExtX );
988 GDI_ReleaseObj( hdc );
989 return ret;
993 /***********************************************************************
994 * SetTextCharacterExtra (GDI.8)
996 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
998 return (INT16)SetTextCharacterExtra( hdc, extra );
1002 /***********************************************************************
1003 * SetTextCharacterExtra (GDI32.@)
1005 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
1007 INT prev;
1008 DC * dc = DC_GetDCPtr( hdc );
1009 if (!dc) return 0;
1010 if (dc->funcs->pSetTextCharacterExtra)
1011 prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
1012 else
1014 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
1015 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
1016 dc->charExtra = abs(extra);
1018 GDI_ReleaseObj( hdc );
1019 return prev;
1023 /***********************************************************************
1024 * SetTextJustification (GDI.10)
1026 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
1028 return SetTextJustification( hdc, extra, breaks );
1032 /***********************************************************************
1033 * SetTextJustification (GDI32.@)
1035 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
1037 BOOL ret = TRUE;
1038 DC * dc = DC_GetDCPtr( hdc );
1039 if (!dc) return FALSE;
1040 if (dc->funcs->pSetTextJustification)
1041 ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
1042 else
1044 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
1045 if (!extra) breaks = 0;
1046 dc->breakTotalExtra = extra;
1047 dc->breakCount = breaks;
1048 if (breaks)
1050 dc->breakExtra = extra / breaks;
1051 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
1053 else
1055 dc->breakExtra = 0;
1056 dc->breakRem = 0;
1059 GDI_ReleaseObj( hdc );
1060 return ret;
1064 /***********************************************************************
1065 * GetTextFace (GDI.92)
1067 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
1069 return GetTextFaceA(hdc,count,name);
1072 /***********************************************************************
1073 * GetTextFaceA (GDI32.@)
1075 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
1077 INT res = GetTextFaceW(hdc, 0, NULL);
1078 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
1079 GetTextFaceW( hdc, res, nameW );
1081 if (name)
1082 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
1083 NULL, NULL);
1084 else
1085 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
1086 HeapFree( GetProcessHeap(), 0, nameW );
1087 return res;
1090 /***********************************************************************
1091 * GetTextFaceW (GDI32.@)
1093 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
1095 FONTOBJ *font;
1096 INT ret = 0;
1098 DC * dc = DC_GetDCPtr( hdc );
1099 if (!dc) return 0;
1101 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1103 if (name)
1105 lstrcpynW( name, font->logfont.lfFaceName, count );
1106 ret = strlenW(name);
1108 else ret = strlenW(font->logfont.lfFaceName) + 1;
1109 GDI_ReleaseObj( dc->hFont );
1111 GDI_ReleaseObj( hdc );
1112 return ret;
1116 /***********************************************************************
1117 * GetTextExtent (GDI.91)
1119 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1121 SIZE16 size;
1122 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1123 return MAKELONG( size.cx, size.cy );
1127 /***********************************************************************
1128 * GetTextExtentPoint (GDI.471)
1130 * FIXME: Should this have a bug for compatibility?
1131 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1132 * bugs (-> MSDN KB q147647.txt).
1134 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1135 LPSIZE16 size )
1137 SIZE size32;
1138 BOOL ret;
1139 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1140 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1141 size->cx = size32.cx;
1142 size->cy = size32.cy;
1143 return (BOOL16)ret;
1147 /***********************************************************************
1148 * GetTextExtentPoint32A (GDI32.@)
1150 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1151 LPSIZE size )
1153 BOOL ret = FALSE;
1154 INT wlen;
1155 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1157 if (p) {
1158 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1159 HeapFree( GetProcessHeap(), 0, p );
1162 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1163 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1164 return ret;
1168 /***********************************************************************
1169 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1171 * Computes width and height of the specified string.
1173 * RETURNS
1174 * Success: TRUE
1175 * Failure: FALSE
1177 BOOL WINAPI GetTextExtentPoint32W(
1178 HDC hdc, /* [in] Handle of device context */
1179 LPCWSTR str, /* [in] Address of text string */
1180 INT count, /* [in] Number of characters in string */
1181 LPSIZE size) /* [out] Address of structure for string size */
1183 BOOL ret = FALSE;
1184 DC * dc = DC_GetDCPtr( hdc );
1185 if (!dc) return FALSE;
1187 if(dc->gdiFont) {
1188 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1189 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1190 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1192 else if(dc->funcs->pGetTextExtentPoint)
1193 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1195 GDI_ReleaseObj( hdc );
1197 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1198 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1199 return ret;
1202 /***********************************************************************
1203 * GetTextExtentPointI [GDI32.@]
1205 * Computes width and height of the array of glyph indices.
1207 * RETURNS
1208 * Success: TRUE
1209 * Failure: FALSE
1211 BOOL WINAPI GetTextExtentPointI(
1212 HDC hdc, /* [in] Handle of device context */
1213 const WORD *indices, /* [in] Address of glyph index array */
1214 INT count, /* [in] Number of glyphs in array */
1215 LPSIZE size) /* [out] Address of structure for string size */
1217 BOOL ret = FALSE;
1218 DC * dc = DC_GetDCPtr( hdc );
1219 if (!dc) return FALSE;
1221 if(dc->gdiFont) {
1222 ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1223 size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1224 size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1226 else if(dc->funcs->pGetTextExtentPoint) {
1227 FIXME("calling GetTextExtentPoint\n");
1228 ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1231 GDI_ReleaseObj( hdc );
1233 TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1234 hdc, indices, count, size, size->cx, size->cy );
1235 return ret;
1239 /***********************************************************************
1240 * GetTextExtentPointA (GDI32.@)
1242 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1243 LPSIZE size )
1245 TRACE("not bug compatible.\n");
1246 return GetTextExtentPoint32A( hdc, str, count, size );
1249 /***********************************************************************
1250 * GetTextExtentPointW (GDI32.@)
1252 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1253 LPSIZE size )
1255 TRACE("not bug compatible.\n");
1256 return GetTextExtentPoint32W( hdc, str, count, size );
1260 /***********************************************************************
1261 * GetTextExtentExPointA (GDI32.@)
1263 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1264 INT maxExt, LPINT lpnFit,
1265 LPINT alpDx, LPSIZE size )
1267 BOOL ret;
1268 INT wlen;
1269 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1270 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1271 HeapFree( GetProcessHeap(), 0, p );
1272 return ret;
1276 /***********************************************************************
1277 * GetTextExtentExPointW (GDI32.@)
1279 * Return the size of the string as it would be if it was output properly by
1280 * e.g. TextOut.
1282 * This should include
1283 * - Intercharacter spacing
1284 * - justification spacing (not yet done)
1285 * - kerning? see below
1287 * Kerning. Since kerning would be carried out by the rendering code it should
1288 * be done by the driver. However they don't support it yet. Also I am not
1289 * yet persuaded that (certainly under Win95) any kerning is actually done.
1291 * str: According to MSDN this should be null-terminated. That is not true; a
1292 * null will not terminate it early.
1293 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1294 * than count. I have seen it be either the size of the full string or
1295 * 1 less than the size of the full string. I have not seen it bear any
1296 * resemblance to the portion that would fit.
1297 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1298 * trailing intercharacter spacing and any trailing justification.
1300 * FIXME
1301 * Currently we do this by measuring each character etc. We should do it by
1302 * passing the request to the driver, perhaps by extending the
1303 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1304 * thinking about kerning issues and rounding issues in the justification.
1307 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1308 INT maxExt, LPINT lpnFit,
1309 LPINT alpDx, LPSIZE size )
1311 int index, nFit, extent;
1312 SIZE tSize;
1313 BOOL ret = FALSE;
1315 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1317 size->cx = size->cy = nFit = extent = 0;
1318 for(index = 0; index < count; index++)
1320 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1321 /* GetTextExtentPoint includes intercharacter spacing. */
1322 /* FIXME - justification needs doing yet. Remember that the base
1323 * data will not be in logical coordinates.
1325 extent += tSize.cx;
1326 if( !lpnFit || extent <= maxExt )
1327 /* It is allowed to be equal. */
1329 nFit++;
1330 if( alpDx ) alpDx[index] = extent;
1332 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1333 str++;
1335 size->cx = extent;
1336 if(lpnFit) *lpnFit = nFit;
1337 ret = TRUE;
1339 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1341 done:
1342 return ret;
1345 /***********************************************************************
1346 * GetTextMetrics (GDI.93)
1348 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1350 TEXTMETRICW tm32;
1352 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1353 FONT_TextMetricWTo16( &tm32, metrics );
1354 return TRUE;
1358 /***********************************************************************
1359 * GetTextMetricsA (GDI32.@)
1361 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1363 TEXTMETRICW tm32;
1365 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1366 FONT_TextMetricWToA( &tm32, metrics );
1367 return TRUE;
1370 /***********************************************************************
1371 * GetTextMetricsW (GDI32.@)
1373 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1375 BOOL ret = FALSE;
1376 DC * dc = DC_GetDCPtr( hdc );
1377 if (!dc) return FALSE;
1379 if (dc->gdiFont)
1380 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1381 else if (dc->funcs->pGetTextMetrics)
1382 ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1384 if (ret)
1386 /* device layer returns values in device units
1387 * therefore we have to convert them to logical */
1389 #define WDPTOLP(x) ((x<0)? \
1390 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1391 (abs((x)*dc->wndExtX/dc->vportExtX)))
1392 #define HDPTOLP(y) ((y<0)? \
1393 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1394 (abs((y)*dc->wndExtY/dc->vportExtY)))
1396 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1397 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1398 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1399 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1400 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1401 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1402 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1403 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1404 ret = TRUE;
1406 TRACE("text metrics:\n"
1407 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1408 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1409 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1410 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1411 " PitchAndFamily = %02x\n"
1412 " --------------------\n"
1413 " InternalLeading = %li\n"
1414 " Ascent = %li\n"
1415 " Descent = %li\n"
1416 " Height = %li\n",
1417 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1418 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1419 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1420 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1421 metrics->tmPitchAndFamily,
1422 metrics->tmInternalLeading,
1423 metrics->tmAscent,
1424 metrics->tmDescent,
1425 metrics->tmHeight );
1427 GDI_ReleaseObj( hdc );
1428 return ret;
1432 /***********************************************************************
1433 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1435 * NOTES
1436 * lpOTM should be LPOUTLINETEXTMETRIC
1438 * RETURNS
1439 * Success: Non-zero or size of required buffer
1440 * Failure: 0
1442 UINT16 WINAPI GetOutlineTextMetrics16(
1443 HDC16 hdc, /* [in] Handle of device context */
1444 UINT16 cbData, /* [in] Size of metric data array */
1445 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1447 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1448 return 0;
1452 /***********************************************************************
1453 * GetOutlineTextMetricsA (GDI32.@)
1454 * Gets metrics for TrueType fonts.
1457 * RETURNS
1458 * Success: Non-zero or size of required buffer
1459 * Failure: 0
1461 UINT WINAPI GetOutlineTextMetricsA(
1462 HDC hdc, /* [in] Handle of device context */
1463 UINT cbData, /* [in] Size of metric data array */
1464 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1466 char buf[512], *ptr;
1467 UINT ret, needed;
1468 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1469 INT left, len;
1471 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1472 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1473 return 0;
1474 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1475 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1478 needed = sizeof(OUTLINETEXTMETRICA);
1479 if(lpOTMW->otmpFamilyName)
1480 needed += WideCharToMultiByte(CP_ACP, 0,
1481 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1482 NULL, 0, NULL, NULL);
1483 if(lpOTMW->otmpFaceName)
1484 needed += WideCharToMultiByte(CP_ACP, 0,
1485 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1486 NULL, 0, NULL, NULL);
1487 if(lpOTMW->otmpStyleName)
1488 needed += WideCharToMultiByte(CP_ACP, 0,
1489 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1490 NULL, 0, NULL, NULL);
1491 if(lpOTMW->otmpFullName)
1492 needed += WideCharToMultiByte(CP_ACP, 0,
1493 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1494 NULL, 0, NULL, NULL);
1496 if(!lpOTM) {
1497 ret = needed;
1498 goto end;
1501 if(needed > cbData) {
1502 ret = 0;
1503 goto end;
1507 lpOTM->otmSize = needed;
1508 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1509 lpOTM->otmFiller = 0;
1510 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1511 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1512 lpOTM->otmfsType = lpOTMW->otmfsType;
1513 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1514 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1515 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1516 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1517 lpOTM->otmAscent = lpOTMW->otmAscent;
1518 lpOTM->otmDescent = lpOTMW->otmDescent;
1519 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1520 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1521 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1522 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1523 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1524 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1525 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1526 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1527 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1528 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1529 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1530 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1531 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1532 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1533 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1534 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1537 ptr = (char*)(lpOTM + 1);
1538 left = needed - sizeof(*lpOTM);
1540 if(lpOTMW->otmpFamilyName) {
1541 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1542 len = WideCharToMultiByte(CP_ACP, 0,
1543 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1544 ptr, left, NULL, NULL);
1545 left -= len;
1546 ptr += len;
1547 } else
1548 lpOTM->otmpFamilyName = 0;
1550 if(lpOTMW->otmpFaceName) {
1551 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1552 len = WideCharToMultiByte(CP_ACP, 0,
1553 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1554 ptr, left, NULL, NULL);
1555 left -= len;
1556 ptr += len;
1557 } else
1558 lpOTM->otmpFaceName = 0;
1560 if(lpOTMW->otmpStyleName) {
1561 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1562 len = WideCharToMultiByte(CP_ACP, 0,
1563 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1564 ptr, left, NULL, NULL);
1565 left -= len;
1566 ptr += len;
1567 } else
1568 lpOTM->otmpStyleName = 0;
1570 if(lpOTMW->otmpFullName) {
1571 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1572 len = WideCharToMultiByte(CP_ACP, 0,
1573 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1574 ptr, left, NULL, NULL);
1575 left -= len;
1576 } else
1577 lpOTM->otmpFullName = 0;
1579 assert(left == 0);
1581 ret = needed;
1583 end:
1584 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1585 HeapFree(GetProcessHeap(), 0, lpOTMW);
1587 return ret;
1591 /***********************************************************************
1592 * GetOutlineTextMetricsW [GDI32.@]
1594 UINT WINAPI GetOutlineTextMetricsW(
1595 HDC hdc, /* [in] Handle of device context */
1596 UINT cbData, /* [in] Size of metric data array */
1597 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1599 DC *dc = DC_GetDCPtr( hdc );
1600 UINT ret;
1602 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1603 if(!dc) return 0;
1605 if(dc->gdiFont)
1606 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1608 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1609 but really this should just be a return 0. */
1611 ret = sizeof(*lpOTM);
1612 if (lpOTM) {
1613 if(cbData < ret)
1614 ret = 0;
1615 else {
1616 memset(lpOTM, 0, ret);
1617 lpOTM->otmSize = sizeof(*lpOTM);
1618 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1620 Further fill of the structure not implemented,
1621 Needs real values for the structure members
1626 GDI_ReleaseObj(hdc);
1627 return ret;
1631 /***********************************************************************
1632 * GetCharWidth (GDI.350)
1634 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1635 LPINT16 buffer )
1637 BOOL retVal = FALSE;
1639 if( firstChar != lastChar )
1641 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1642 sizeof(INT)*(1 + (lastChar - firstChar)));
1643 if( buf32 )
1645 LPINT obuf32 = buf32;
1646 int i;
1648 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1649 if (retVal)
1651 for (i = firstChar; i <= lastChar; i++)
1652 *buffer++ = *buf32++;
1654 HeapFree(GetProcessHeap(), 0, obuf32);
1657 else /* happens quite often to warrant a special treatment */
1659 INT chWidth;
1660 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1661 *buffer = chWidth;
1663 return retVal;
1667 /***********************************************************************
1668 * GetCharWidthW (GDI32.@)
1669 * GetCharWidth32W (GDI32.@)
1671 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1672 LPINT buffer )
1674 UINT i, extra;
1675 BOOL ret = FALSE;
1676 DC * dc = DC_GetDCPtr( hdc );
1677 if (!dc) return FALSE;
1679 if (dc->gdiFont)
1680 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1681 else if (dc->funcs->pGetCharWidth)
1682 ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1684 if (ret)
1686 /* convert device units to logical */
1688 extra = dc->vportExtX >> 1;
1689 for( i = firstChar; i <= lastChar; i++, buffer++ )
1690 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1691 ret = TRUE;
1693 GDI_ReleaseObj( hdc );
1694 return ret;
1698 /***********************************************************************
1699 * GetCharWidthA (GDI32.@)
1700 * GetCharWidth32A (GDI32.@)
1702 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1703 LPINT buffer )
1705 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1706 LPSTR str;
1707 LPWSTR wstr;
1708 BOOL ret = TRUE;
1710 if(count <= 0) return FALSE;
1712 str = HeapAlloc(GetProcessHeap(), 0, count);
1713 for(i = 0; i < count; i++)
1714 str[i] = (BYTE)(firstChar + i);
1716 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1718 for(i = 0; i < wlen; i++)
1720 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1722 ret = FALSE;
1723 break;
1725 buffer++;
1728 HeapFree(GetProcessHeap(), 0, str);
1729 HeapFree(GetProcessHeap(), 0, wstr);
1731 return ret;
1735 /* FIXME: all following APIs ******************************************/
1738 /***********************************************************************
1739 * SetMapperFlags (GDI.349)
1741 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1743 return SetMapperFlags( hDC, dwFlag );
1747 /***********************************************************************
1748 * SetMapperFlags (GDI32.@)
1750 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1752 DC *dc = DC_GetDCPtr( hDC );
1753 DWORD ret = 0;
1754 if(!dc) return 0;
1755 if(dc->funcs->pSetMapperFlags)
1756 ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1757 else
1758 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1759 GDI_ReleaseObj( hDC );
1760 return ret;
1763 /***********************************************************************
1764 * GetAspectRatioFilterEx (GDI.486)
1766 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1768 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1769 return FALSE;
1772 /***********************************************************************
1773 * GetAspectRatioFilterEx (GDI32.@)
1775 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1777 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1778 return FALSE;
1781 /***********************************************************************
1782 * GetCharABCWidths (GDI.307)
1784 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1785 LPABC16 abc )
1787 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1788 int i;
1790 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1791 HeapFree(GetProcessHeap(),0,abc32);
1792 return FALSE;
1795 for (i=firstChar;i<=lastChar;i++) {
1796 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1797 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1798 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1800 HeapFree(GetProcessHeap(),0,abc32);
1801 return TRUE;
1805 /***********************************************************************
1806 * GetCharABCWidthsA (GDI32.@)
1808 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1809 LPABC abc )
1811 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1812 LPSTR str;
1813 LPWSTR wstr;
1814 BOOL ret = TRUE;
1816 if(count <= 0) return FALSE;
1818 str = HeapAlloc(GetProcessHeap(), 0, count);
1819 for(i = 0; i < count; i++)
1820 str[i] = (BYTE)(firstChar + i);
1822 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1824 for(i = 0; i < wlen; i++)
1826 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1828 ret = FALSE;
1829 break;
1831 abc++;
1834 HeapFree(GetProcessHeap(), 0, str);
1835 HeapFree(GetProcessHeap(), 0, wstr);
1837 return ret;
1841 /******************************************************************************
1842 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1844 * PARAMS
1845 * hdc [I] Handle of device context
1846 * firstChar [I] First character in range to query
1847 * lastChar [I] Last character in range to query
1848 * abc [O] Address of character-width structure
1850 * NOTES
1851 * Only works with TrueType fonts
1853 * RETURNS
1854 * Success: TRUE
1855 * Failure: FALSE
1857 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1858 LPABC abc )
1860 DC *dc = DC_GetDCPtr(hdc);
1861 int i;
1862 GLYPHMETRICS gm;
1863 BOOL ret = FALSE;
1865 if(dc->gdiFont) {
1866 for (i=firstChar;i<=lastChar;i++) {
1867 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1868 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1869 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1870 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1872 ret = TRUE;
1874 GDI_ReleaseObj(hdc);
1875 return ret;
1879 /***********************************************************************
1880 * GetGlyphOutline (GDI.309)
1882 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1883 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1884 LPVOID lpBuffer, const MAT2 *lpmat2 )
1886 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1887 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1888 return (DWORD)-1; /* failure */
1892 /***********************************************************************
1893 * GetGlyphOutlineA (GDI32.@)
1895 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1896 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1897 LPVOID lpBuffer, const MAT2 *lpmat2 )
1899 LPWSTR p = NULL;
1900 DWORD ret;
1901 UINT c;
1903 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1904 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1905 c = p[0];
1906 } else
1907 c = uChar;
1908 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1909 lpmat2);
1910 if(p)
1911 HeapFree(GetProcessHeap(), 0, p);
1912 return ret;
1915 /***********************************************************************
1916 * GetGlyphOutlineW (GDI32.@)
1918 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1919 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1920 LPVOID lpBuffer, const MAT2 *lpmat2 )
1922 DC *dc = DC_GetDCPtr(hdc);
1923 DWORD ret;
1925 TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1926 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1928 if(!dc) return GDI_ERROR;
1930 if(dc->gdiFont)
1931 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1932 cbBuffer, lpBuffer, lpmat2);
1933 else
1934 ret = GDI_ERROR;
1936 GDI_ReleaseObj(hdc);
1937 return ret;
1940 /***********************************************************************
1941 * CreateScalableFontResource (GDI.310)
1943 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1944 LPCSTR lpszResourceFile,
1945 LPCSTR fontFile, LPCSTR path )
1947 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1948 fontFile, path );
1951 /***********************************************************************
1952 * CreateScalableFontResourceA (GDI32.@)
1954 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1955 LPCSTR lpszResourceFile,
1956 LPCSTR lpszFontFile,
1957 LPCSTR lpszCurrentPath )
1959 /* fHidden=1 - only visible for the calling app, read-only, not
1960 * enumbered with EnumFonts/EnumFontFamilies
1961 * lpszCurrentPath can be NULL
1963 FIXME("(%ld,%s,%s,%s): stub\n",
1964 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1965 debugstr_a(lpszCurrentPath) );
1966 return FALSE; /* create failed */
1969 /***********************************************************************
1970 * CreateScalableFontResourceW (GDI32.@)
1972 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1973 LPCWSTR lpszResourceFile,
1974 LPCWSTR lpszFontFile,
1975 LPCWSTR lpszCurrentPath )
1977 FIXME("(%ld,%p,%p,%p): stub\n",
1978 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1979 return FALSE; /* create failed */
1983 /*************************************************************************
1984 * GetRasterizerCaps (GDI.313)
1986 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1988 return GetRasterizerCaps( lprs, cbNumBytes );
1992 /*************************************************************************
1993 * GetRasterizerCaps (GDI32.@)
1995 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1997 lprs->nSize = sizeof(RASTERIZER_STATUS);
1998 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1999 lprs->nLanguageID = 0;
2000 return TRUE;
2004 /*************************************************************************
2005 * GetKerningPairs (GDI.332)
2008 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
2009 LPKERNINGPAIR16 lpKerningPairs )
2011 /* At this time kerning is ignored (set to 0) */
2012 int i;
2013 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2014 if (lpKerningPairs)
2015 for (i = 0; i < cPairs; i++)
2016 lpKerningPairs[i].iKernAmount = 0;
2017 /* FIXME: Should this function call SetLastError (0)? This is yet another
2018 * Microsoft function that can return 0 on success or failure
2020 return 0;
2025 /*************************************************************************
2026 * GetKerningPairsA (GDI32.@)
2028 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2029 LPKERNINGPAIR lpKerningPairs )
2031 int i;
2032 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2033 for (i = 0; i < cPairs; i++)
2034 lpKerningPairs[i].iKernAmount = 0;
2035 return 0;
2039 /*************************************************************************
2040 * GetKerningPairsW (GDI32.@)
2042 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2043 LPKERNINGPAIR lpKerningPairs )
2045 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
2048 /*************************************************************************
2049 * TranslateCharsetInfo [GDI32.@]
2050 * TranslateCharsetInfo [USER32.@]
2052 * Fills a CHARSETINFO structure for a character set, code page, or
2053 * font. This allows making the correspondance between different labelings
2054 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2055 * of the same encoding.
2057 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2058 * only one codepage should be set in *lpSrc.
2060 * RETURNS
2061 * TRUE on success, FALSE on failure.
2064 BOOL WINAPI TranslateCharsetInfo(
2065 LPDWORD lpSrc, /* [in]
2066 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2067 if flags == TCI_SRCCHARSET: a character set value
2068 if flags == TCI_SRCCODEPAGE: a code page value
2070 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2071 DWORD flags /* [in] determines interpretation of lpSrc */
2073 int index = 0;
2074 switch (flags) {
2075 case TCI_SRCFONTSIG:
2076 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2077 break;
2078 case TCI_SRCCODEPAGE:
2079 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2080 break;
2081 case TCI_SRCCHARSET:
2082 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2083 break;
2084 default:
2085 return FALSE;
2087 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2088 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2089 return TRUE;
2092 /*************************************************************************
2093 * GetFontLanguageInfo (GDI32.@)
2095 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
2096 /* return value 0 is correct for most cases anyway */
2097 FIXME("(%x):stub!\n", hdc);
2098 return 0;
2101 /*************************************************************************
2102 * GetFontLanguageInfo (GDI.616)
2104 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
2105 /* return value 0 is correct for most cases anyway */
2106 FIXME("(%x):stub!\n",hdc);
2107 return 0;
2110 /*************************************************************************
2111 * GetFontData [GDI32.@] Retrieve data for TrueType font
2113 * RETURNS
2115 * success: Number of bytes returned
2116 * failure: GDI_ERROR
2118 * NOTES
2120 * Calls SetLastError()
2123 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2124 LPVOID buffer, DWORD length)
2126 DC *dc = DC_GetDCPtr(hdc);
2127 DWORD ret = GDI_ERROR;
2129 if(!dc) return GDI_ERROR;
2131 if(dc->gdiFont)
2132 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2134 GDI_ReleaseObj(hdc);
2135 return ret;
2138 /*************************************************************************
2139 * GetFontData [GDI.311]
2142 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2143 LPVOID lpvBuffer, DWORD cbData)
2145 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2148 /*************************************************************************
2149 * GetGlyphIndicesA [GDI32.@]
2151 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2152 LPWORD pgi, DWORD flags)
2154 DWORD ret;
2155 WCHAR *lpstrW;
2156 INT countW;
2158 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2159 hdc, debugstr_an(lpstr, count), count, pgi, flags);
2161 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2162 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2163 HeapFree(GetProcessHeap(), 0, lpstrW);
2165 return ret;
2168 /*************************************************************************
2169 * GetGlyphIndicesW [GDI32.@]
2171 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2172 LPWORD pgi, DWORD flags)
2174 DC *dc = DC_GetDCPtr(hdc);
2175 DWORD ret = GDI_ERROR;
2177 TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2178 hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2180 if(!dc) return GDI_ERROR;
2182 if(dc->gdiFont)
2183 ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2185 GDI_ReleaseObj(hdc);
2186 return ret;
2189 /*************************************************************************
2190 * GetCharacterPlacementA [GDI32.@]
2192 * NOTES:
2193 * the web browser control of ie4 calls this with dwFlags=0
2195 DWORD WINAPI
2196 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2197 INT nMaxExtent, GCP_RESULTSA *lpResults,
2198 DWORD dwFlags)
2200 WCHAR *lpStringW;
2201 INT uCountW;
2202 GCP_RESULTSW resultsW;
2203 DWORD ret;
2204 UINT font_cp;
2206 TRACE("%s, %d, %d, 0x%08lx\n",
2207 debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2209 /* both structs are equal in size */
2210 memcpy(&resultsW, lpResults, sizeof(resultsW));
2212 lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2213 if(lpResults->lpOutString)
2214 resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2215 else
2216 resultsW.lpOutString = NULL;
2218 ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2220 if(lpResults->lpOutString)
2221 WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2222 lpResults->lpOutString, uCount, NULL, NULL );
2224 HeapFree(GetProcessHeap(), 0, lpStringW);
2225 HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2227 return ret;
2230 /*************************************************************************
2231 * GetCharacterPlacementW [GDI32.@]
2233 DWORD WINAPI
2234 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
2235 INT nMaxExtent, GCP_RESULTSW *lpResults,
2236 DWORD dwFlags)
2238 DWORD ret=0;
2239 SIZE size;
2240 UINT i, nSet;
2242 TRACE("%s, %d, %d, 0x%08lx\n",
2243 debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2245 TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2246 "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2247 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2248 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2249 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2251 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
2252 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2253 if(lpResults->lpClass) FIXME("classes not implemented\n");
2255 /* FIXME: reordering not implemented */
2256 /* copy will do if the GCP_REORDER flag is not set */
2257 if(lpResults->lpOutString)
2258 lstrcpynW(lpResults->lpOutString, lpString, uCount);
2260 nSet = (UINT)uCount;
2261 if(nSet > lpResults->nGlyphs)
2262 nSet = lpResults->nGlyphs;
2264 /* return number of initialized fields */
2265 lpResults->nGlyphs = nSet;
2267 if(lpResults->lpOrder)
2269 for(i = 0; i < nSet; i++)
2270 lpResults->lpOrder[i] = i;
2273 if (lpResults->lpDx)
2275 int c;
2276 for (i = 0; i < nSet; i++)
2278 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2279 lpResults->lpDx[i]= c;
2283 if(lpResults->lpGlyphs)
2284 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2286 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2287 ret = MAKELONG(size.cx, size.cy);
2289 return ret;
2292 /*************************************************************************
2293 * GetCharABCWidthsFloatA [GDI32.@]
2295 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2296 LPABCFLOAT lpABCF)
2298 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2299 return 0;
2302 /*************************************************************************
2303 * GetCharABCWidthsFloatW [GDI32.@]
2305 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2306 UINT iLastChar, LPABCFLOAT lpABCF)
2308 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2309 return 0;
2312 /*************************************************************************
2313 * GetCharWidthFloatA [GDI32.@]
2315 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2316 UINT iLastChar, PFLOAT pxBuffer)
2318 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2319 return 0;
2322 /*************************************************************************
2323 * GetCharWidthFloatW [GDI32.@]
2325 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2326 UINT iLastChar, PFLOAT pxBuffer)
2328 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2329 return 0;
2333 /***********************************************************************
2335 * Font Resource API *
2337 ***********************************************************************/
2338 /***********************************************************************
2339 * AddFontResource (GDI.119)
2341 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2343 * FIXME: Load header and find the best-matching font in the fontList;
2344 * fixup dfPoints if all metrics are identical, otherwise create
2345 * new fontAlias. When soft font support is ready this will
2346 * simply create a new fontResource ('filename' will go into
2347 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
2348 * flag set.
2350 INT16 WINAPI AddFontResource16( LPCSTR filename )
2352 return AddFontResourceA( filename );
2356 /***********************************************************************
2357 * AddFontResourceA (GDI32.@)
2359 INT WINAPI AddFontResourceA( LPCSTR str )
2361 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2362 "this font manually.\n", debugstr_a(str));
2363 return 1;
2367 /***********************************************************************
2368 * AddFontResourceW (GDI32.@)
2370 INT WINAPI AddFontResourceW( LPCWSTR str )
2372 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2373 "this font manually.\n", debugstr_w(str));
2374 return 1;
2377 /***********************************************************************
2378 * RemoveFontResource (GDI.136)
2380 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2382 FIXME("(%s): stub\n", debugstr_a(str));
2383 return TRUE;
2387 /***********************************************************************
2388 * RemoveFontResourceA (GDI32.@)
2390 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2392 /* This is how it should look like */
2394 fontResource** ppfr;
2395 BOOL32 retVal = FALSE;
2397 EnterCriticalSection( &crtsc_fonts_X11 );
2398 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2399 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2401 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2402 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2404 if( (*ppfr)->fo_count )
2405 (*ppfr)->fr_flags |= FR_REMOVED;
2406 else
2407 XFONT_RemoveFontResource( ppfr );
2409 retVal = TRUE;
2411 LeaveCriticalSection( &crtsc_fonts_X11 );
2412 return retVal;
2414 FIXME("(%s): stub\n", debugstr_a(str));
2415 return TRUE;
2419 /***********************************************************************
2420 * RemoveFontResourceW (GDI32.@)
2422 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2424 FIXME("(%s): stub\n", debugstr_w(str) );
2425 return TRUE;