Added LGPL standard comment, and copyright notices where necessary.
[wine/multimedia.git] / objects / font.c
blobad0add9e68cb245b73bdcd36ae70dcea5338afaf
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 #include "winerror.h"
26 #include "winnls.h"
27 #include "wine/unicode.h"
28 #include "font.h"
29 #include "options.h"
30 #include "wine/debug.h"
31 #include "gdi.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(font);
34 WINE_DECLARE_DEBUG_CHANNEL(gdi);
36 #define ENUM_UNICODE 0x00000001
38 typedef struct
40 LPLOGFONT16 lpLogFontParam;
41 FONTENUMPROCEX16 lpEnumFunc;
42 LPARAM lpData;
44 LPNEWTEXTMETRICEX16 lpTextMetric;
45 LPENUMLOGFONTEX16 lpLogFont;
46 SEGPTR segTextMetric;
47 SEGPTR segLogFont;
48 } fontEnum16;
50 typedef struct
52 LPLOGFONTW lpLogFontParam;
53 FONTENUMPROCEXW lpEnumFunc;
54 LPARAM lpData;
56 DWORD dwFlags;
57 } fontEnum32;
60 * For TranslateCharsetInfo
62 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
63 #define MAXTCIINDEX 32
64 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
65 /* ANSI */
66 { ANSI_CHARSET, 1252, FS(0)},
67 { EASTEUROPE_CHARSET, 1250, FS(1)},
68 { RUSSIAN_CHARSET, 1251, FS(2)},
69 { GREEK_CHARSET, 1253, FS(3)},
70 { TURKISH_CHARSET, 1254, FS(4)},
71 { HEBREW_CHARSET, 1255, FS(5)},
72 { ARABIC_CHARSET, 1256, FS(6)},
73 { BALTIC_CHARSET, 1257, FS(7)},
74 /* reserved by ANSI */
75 { DEFAULT_CHARSET, 0, FS(0)},
76 { DEFAULT_CHARSET, 0, FS(0)},
77 { DEFAULT_CHARSET, 0, FS(0)},
78 { DEFAULT_CHARSET, 0, FS(0)},
79 { DEFAULT_CHARSET, 0, FS(0)},
80 { DEFAULT_CHARSET, 0, FS(0)},
81 { DEFAULT_CHARSET, 0, FS(0)},
82 { DEFAULT_CHARSET, 0, FS(0)},
83 /* ANSI and OEM */
84 { THAI_CHARSET, 874, FS(16)},
85 { SHIFTJIS_CHARSET, 932, FS(17)},
86 { GB2312_CHARSET, 936, FS(18)},
87 { HANGEUL_CHARSET, 949, FS(19)},
88 { CHINESEBIG5_CHARSET, 950, FS(20)},
89 { JOHAB_CHARSET, 1361, FS(21)},
90 /* reserved for alternate ANSI and OEM */
91 { DEFAULT_CHARSET, 0, FS(0)},
92 { DEFAULT_CHARSET, 0, FS(0)},
93 { DEFAULT_CHARSET, 0, FS(0)},
94 { DEFAULT_CHARSET, 0, FS(0)},
95 { DEFAULT_CHARSET, 0, FS(0)},
96 { DEFAULT_CHARSET, 0, FS(0)},
97 { DEFAULT_CHARSET, 0, FS(0)},
98 { DEFAULT_CHARSET, 0, FS(0)},
99 /* reserved for system */
100 { DEFAULT_CHARSET, 0, FS(0)},
101 { DEFAULT_CHARSET, 0, FS(0)},
104 /* ### start build ### */
105 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
106 /* ### stop build ### */
108 /***********************************************************************
109 * LOGFONT conversion functions.
111 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
113 font16->lfHeight = font32->lfHeight;
114 font16->lfWidth = font32->lfWidth;
115 font16->lfEscapement = font32->lfEscapement;
116 font16->lfOrientation = font32->lfOrientation;
117 font16->lfWeight = font32->lfWeight;
118 font16->lfItalic = font32->lfItalic;
119 font16->lfUnderline = font32->lfUnderline;
120 font16->lfStrikeOut = font32->lfStrikeOut;
121 font16->lfCharSet = font32->lfCharSet;
122 font16->lfOutPrecision = font32->lfOutPrecision;
123 font16->lfClipPrecision = font32->lfClipPrecision;
124 font16->lfQuality = font32->lfQuality;
125 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
126 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
129 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
131 font16->lfHeight = font32->lfHeight;
132 font16->lfWidth = font32->lfWidth;
133 font16->lfEscapement = font32->lfEscapement;
134 font16->lfOrientation = font32->lfOrientation;
135 font16->lfWeight = font32->lfWeight;
136 font16->lfItalic = font32->lfItalic;
137 font16->lfUnderline = font32->lfUnderline;
138 font16->lfStrikeOut = font32->lfStrikeOut;
139 font16->lfCharSet = font32->lfCharSet;
140 font16->lfOutPrecision = font32->lfOutPrecision;
141 font16->lfClipPrecision = font32->lfClipPrecision;
142 font16->lfQuality = font32->lfQuality;
143 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
144 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
145 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
146 font16->lfFaceName[LF_FACESIZE-1] = 0;
149 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
151 font32->lfHeight = font16->lfHeight;
152 font32->lfWidth = font16->lfWidth;
153 font32->lfEscapement = font16->lfEscapement;
154 font32->lfOrientation = font16->lfOrientation;
155 font32->lfWeight = font16->lfWeight;
156 font32->lfItalic = font16->lfItalic;
157 font32->lfUnderline = font16->lfUnderline;
158 font32->lfStrikeOut = font16->lfStrikeOut;
159 font32->lfCharSet = font16->lfCharSet;
160 font32->lfOutPrecision = font16->lfOutPrecision;
161 font32->lfClipPrecision = font16->lfClipPrecision;
162 font32->lfQuality = font16->lfQuality;
163 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
164 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
167 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
169 font32->lfHeight = font16->lfHeight;
170 font32->lfWidth = font16->lfWidth;
171 font32->lfEscapement = font16->lfEscapement;
172 font32->lfOrientation = font16->lfOrientation;
173 font32->lfWeight = font16->lfWeight;
174 font32->lfItalic = font16->lfItalic;
175 font32->lfUnderline = font16->lfUnderline;
176 font32->lfStrikeOut = font16->lfStrikeOut;
177 font32->lfCharSet = font16->lfCharSet;
178 font32->lfOutPrecision = font16->lfOutPrecision;
179 font32->lfClipPrecision = font16->lfClipPrecision;
180 font32->lfQuality = font16->lfQuality;
181 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
182 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
183 font32->lfFaceName[LF_FACESIZE-1] = 0;
186 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
188 memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
189 MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
190 LF_FACESIZE);
193 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
195 memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
196 WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
197 LF_FACESIZE, NULL, NULL);
200 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
202 FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
203 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
204 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
205 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
208 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
210 FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
212 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
213 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
214 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
215 font32->elfStyle[LF_FACESIZE-1] = 0;
216 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
217 font32->elfScript[LF_FACESIZE-1] = 0;
220 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
222 FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
224 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
225 font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
226 font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
227 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
228 font16->elfStyle, LF_FACESIZE, NULL, NULL );
229 font16->elfStyle[LF_FACESIZE-1] = '\0';
230 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
231 font16->elfScript, LF_FACESIZE, NULL, NULL );
232 font16->elfScript[LF_FACESIZE-1] = '\0';
235 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
237 FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
239 WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
240 fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
241 fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
242 WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
243 fontA->elfStyle, LF_FACESIZE, NULL, NULL );
244 fontA->elfStyle[LF_FACESIZE-1] = '\0';
245 WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
246 fontA->elfScript, LF_FACESIZE, NULL, NULL );
247 fontA->elfScript[LF_FACESIZE-1] = '\0';
250 /***********************************************************************
251 * TEXTMETRIC conversion functions.
253 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
255 ptm16->tmHeight = ptm32->tmHeight;
256 ptm16->tmAscent = ptm32->tmAscent;
257 ptm16->tmDescent = ptm32->tmDescent;
258 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
259 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
260 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
261 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
262 ptm16->tmWeight = ptm32->tmWeight;
263 ptm16->tmOverhang = ptm32->tmOverhang;
264 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
265 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
266 ptm16->tmFirstChar = ptm32->tmFirstChar;
267 ptm16->tmLastChar = ptm32->tmLastChar;
268 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
269 ptm16->tmBreakChar = ptm32->tmBreakChar;
270 ptm16->tmItalic = ptm32->tmItalic;
271 ptm16->tmUnderlined = ptm32->tmUnderlined;
272 ptm16->tmStruckOut = ptm32->tmStruckOut;
273 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
274 ptm16->tmCharSet = ptm32->tmCharSet;
277 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
279 ptm16->tmHeight = ptm32->tmHeight;
280 ptm16->tmAscent = ptm32->tmAscent;
281 ptm16->tmDescent = ptm32->tmDescent;
282 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
283 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
284 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
285 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
286 ptm16->tmWeight = ptm32->tmWeight;
287 ptm16->tmOverhang = ptm32->tmOverhang;
288 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
289 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
290 ptm16->tmFirstChar = ptm32->tmFirstChar;
291 ptm16->tmLastChar = ptm32->tmLastChar;
292 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
293 ptm16->tmBreakChar = ptm32->tmBreakChar;
294 ptm16->tmItalic = ptm32->tmItalic;
295 ptm16->tmUnderlined = ptm32->tmUnderlined;
296 ptm16->tmStruckOut = ptm32->tmStruckOut;
297 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
298 ptm16->tmCharSet = ptm32->tmCharSet;
301 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
303 ptm32->tmHeight = ptm16->tmHeight;
304 ptm32->tmAscent = ptm16->tmAscent;
305 ptm32->tmDescent = ptm16->tmDescent;
306 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
307 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
308 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
309 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
310 ptm32->tmWeight = ptm16->tmWeight;
311 ptm32->tmOverhang = ptm16->tmOverhang;
312 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
313 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
314 ptm32->tmFirstChar = ptm16->tmFirstChar;
315 ptm32->tmLastChar = ptm16->tmLastChar;
316 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
317 ptm32->tmBreakChar = ptm16->tmBreakChar;
318 ptm32->tmItalic = ptm16->tmItalic;
319 ptm32->tmUnderlined = ptm16->tmUnderlined;
320 ptm32->tmStruckOut = ptm16->tmStruckOut;
321 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
322 ptm32->tmCharSet = ptm16->tmCharSet;
325 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
327 ptm32->tmHeight = ptm16->tmHeight;
328 ptm32->tmAscent = ptm16->tmAscent;
329 ptm32->tmDescent = ptm16->tmDescent;
330 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
331 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
332 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
333 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
334 ptm32->tmWeight = ptm16->tmWeight;
335 ptm32->tmOverhang = ptm16->tmOverhang;
336 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
337 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
338 ptm32->tmFirstChar = ptm16->tmFirstChar;
339 ptm32->tmLastChar = ptm16->tmLastChar;
340 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
341 ptm32->tmBreakChar = ptm16->tmBreakChar;
342 ptm32->tmItalic = ptm16->tmItalic;
343 ptm32->tmUnderlined = ptm16->tmUnderlined;
344 ptm32->tmStruckOut = ptm16->tmStruckOut;
345 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
346 ptm32->tmCharSet = ptm16->tmCharSet;
349 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
351 ptm32W->tmHeight = ptm32A->tmHeight;
352 ptm32W->tmAscent = ptm32A->tmAscent;
353 ptm32W->tmDescent = ptm32A->tmDescent;
354 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
355 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
356 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
357 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
358 ptm32W->tmWeight = ptm32A->tmWeight;
359 ptm32W->tmOverhang = ptm32A->tmOverhang;
360 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
361 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
362 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
363 ptm32W->tmLastChar = ptm32A->tmLastChar;
364 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
365 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
366 ptm32W->tmItalic = ptm32A->tmItalic;
367 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
368 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
369 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
370 ptm32W->tmCharSet = ptm32A->tmCharSet;
373 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
375 ptmA->tmHeight = ptmW->tmHeight;
376 ptmA->tmAscent = ptmW->tmAscent;
377 ptmA->tmDescent = ptmW->tmDescent;
378 ptmA->tmInternalLeading = ptmW->tmInternalLeading;
379 ptmA->tmExternalLeading = ptmW->tmExternalLeading;
380 ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
381 ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
382 ptmA->tmWeight = ptmW->tmWeight;
383 ptmA->tmOverhang = ptmW->tmOverhang;
384 ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
385 ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
386 ptmA->tmFirstChar = ptmW->tmFirstChar;
387 ptmA->tmLastChar = ptmW->tmLastChar;
388 ptmA->tmDefaultChar = ptmW->tmDefaultChar;
389 ptmA->tmBreakChar = ptmW->tmBreakChar;
390 ptmA->tmItalic = ptmW->tmItalic;
391 ptmA->tmUnderlined = ptmW->tmUnderlined;
392 ptmA->tmStruckOut = ptmW->tmStruckOut;
393 ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
394 ptmA->tmCharSet = ptmW->tmCharSet;
398 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
400 FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
401 ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
402 ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
403 ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
404 ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
405 memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
408 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
410 FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
411 ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
412 ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
413 ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
414 ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
415 memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
418 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
420 FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
421 ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
422 ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
423 ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
424 ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
425 memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
429 /***********************************************************************
430 * CreateFontIndirect (GDI.57)
432 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
434 LOGFONTW lfW;
436 if(plf16) {
437 FONT_LogFont16ToW( plf16, &lfW );
438 return CreateFontIndirectW( &lfW );
439 } else {
440 return CreateFontIndirectW( NULL );
445 /***********************************************************************
446 * CreateFontIndirectA (GDI32.@)
448 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
450 LOGFONTW lfW;
452 if (plfA) {
453 FONT_LogFontAToW( plfA, &lfW );
454 return CreateFontIndirectW( &lfW );
455 } else
456 return CreateFontIndirectW( NULL );
460 /***********************************************************************
461 * CreateFontIndirectW (GDI32.@)
463 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
465 HFONT hFont = 0;
467 if (plf)
469 FONTOBJ* fontPtr;
470 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
472 memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
474 TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
475 plf->lfHeight, plf->lfWidth,
476 plf->lfEscapement, plf->lfOrientation,
477 plf->lfPitchAndFamily,
478 debugstr_w(plf->lfFaceName),
479 plf->lfWeight > 400 ? "Bold" : "",
480 plf->lfItalic ? "Italic" : "", hFont);
482 if (plf->lfEscapement != plf->lfOrientation) {
483 /* this should really depend on whether GM_ADVANCED is set */
484 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
485 WARN("orientation angle %f set to "
486 "escapement angle %f for new font %04x\n",
487 plf->lfOrientation/10., plf->lfEscapement/10., hFont);
489 GDI_ReleaseObj( hFont );
492 else WARN("(NULL) => NULL\n");
494 return hFont;
497 /***********************************************************************
498 * CreateFont (GDI.56)
500 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
501 INT16 weight, BYTE italic, BYTE underline,
502 BYTE strikeout, BYTE charset, BYTE outpres,
503 BYTE clippres, BYTE quality, BYTE pitch,
504 LPCSTR name )
506 LOGFONT16 logfont;
508 logfont.lfHeight = height;
509 logfont.lfWidth = width;
510 logfont.lfEscapement = esc;
511 logfont.lfOrientation = orient;
512 logfont.lfWeight = weight;
513 logfont.lfItalic = italic;
514 logfont.lfUnderline = underline;
515 logfont.lfStrikeOut = strikeout;
516 logfont.lfCharSet = charset;
517 logfont.lfOutPrecision = outpres;
518 logfont.lfClipPrecision = clippres;
519 logfont.lfQuality = quality;
520 logfont.lfPitchAndFamily = pitch;
522 if (name)
523 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
524 else
525 logfont.lfFaceName[0] = '\0';
527 return CreateFontIndirect16( &logfont );
530 /*************************************************************************
531 * CreateFontA (GDI32.@)
533 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
534 INT orient, INT weight, DWORD italic,
535 DWORD underline, DWORD strikeout, DWORD charset,
536 DWORD outpres, DWORD clippres, DWORD quality,
537 DWORD pitch, LPCSTR name )
539 LOGFONTA logfont;
541 logfont.lfHeight = height;
542 logfont.lfWidth = width;
543 logfont.lfEscapement = esc;
544 logfont.lfOrientation = orient;
545 logfont.lfWeight = weight;
546 logfont.lfItalic = italic;
547 logfont.lfUnderline = underline;
548 logfont.lfStrikeOut = strikeout;
549 logfont.lfCharSet = charset;
550 logfont.lfOutPrecision = outpres;
551 logfont.lfClipPrecision = clippres;
552 logfont.lfQuality = quality;
553 logfont.lfPitchAndFamily = pitch;
555 if (name)
556 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
557 else
558 logfont.lfFaceName[0] = '\0';
560 return CreateFontIndirectA( &logfont );
563 /*************************************************************************
564 * CreateFontW (GDI32.@)
566 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
567 INT orient, INT weight, DWORD italic,
568 DWORD underline, DWORD strikeout, DWORD charset,
569 DWORD outpres, DWORD clippres, DWORD quality,
570 DWORD pitch, LPCWSTR name )
572 LOGFONTW logfont;
574 logfont.lfHeight = height;
575 logfont.lfWidth = width;
576 logfont.lfEscapement = esc;
577 logfont.lfOrientation = orient;
578 logfont.lfWeight = weight;
579 logfont.lfItalic = italic;
580 logfont.lfUnderline = underline;
581 logfont.lfStrikeOut = strikeout;
582 logfont.lfCharSet = charset;
583 logfont.lfOutPrecision = outpres;
584 logfont.lfClipPrecision = clippres;
585 logfont.lfQuality = quality;
586 logfont.lfPitchAndFamily = pitch;
588 if (name)
589 lstrcpynW(logfont.lfFaceName, name,
590 sizeof(logfont.lfFaceName) / sizeof(WCHAR));
591 else
592 logfont.lfFaceName[0] = '\0';
594 return CreateFontIndirectW( &logfont );
598 /***********************************************************************
599 * FONT_GetObject16
601 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
603 LOGFONT16 lf16;
605 FONT_LogFontWTo16( &font->logfont, &lf16 );
607 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
608 memcpy( buffer, &lf16, count );
609 return count;
612 /***********************************************************************
613 * FONT_GetObjectA
615 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
617 LOGFONTA lfA;
619 FONT_LogFontWToA( &font->logfont, &lfA );
621 if (count > sizeof(lfA)) count = sizeof(lfA);
622 memcpy( buffer, &lfA, count );
623 return count;
625 /***********************************************************************
626 * FONT_GetObjectW
628 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
630 if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
631 memcpy( buffer, &font->logfont, count );
632 return count;
636 /***********************************************************************
637 * FONT_EnumInstance16
639 * Called by the device driver layer to pass font info
640 * down to the application.
642 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
643 DWORD fType, LPARAM lp )
645 #define pfe ((fontEnum16*)lp)
646 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
647 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
649 FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
650 FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
652 return FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
653 (UINT16)fType, (LPARAM)pfe->lpData );
655 #undef pfe
656 return 1;
659 /***********************************************************************
660 * FONT_EnumInstance
662 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
663 DWORD fType, LPARAM lp )
665 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
667 #define pfe ((fontEnum32*)lp)
668 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
669 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
671 /* convert font metrics */
673 if( pfe->dwFlags & ENUM_UNICODE )
675 return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
677 else
679 ENUMLOGFONTEXA logfont;
680 NEWTEXTMETRICEXA tmA;
682 FONT_EnumLogFontExWToA( plf, &logfont);
683 FONT_NewTextMetricExWToA( ptm, &tmA );
685 return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
686 (LPNEWTEXTMETRICEXW)&tmA, fType,
687 pfe->lpData );
690 #undef pfe
691 return 1;
694 /***********************************************************************
695 * EnumFontFamiliesEx (GDI.613)
697 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
698 FONTENUMPROCEX16 efproc, LPARAM lParam,
699 DWORD dwFlags)
701 BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
702 INT16 retVal = 0;
703 DC* dc = DC_GetDCPtr( hDC );
705 if (!dc) return 0;
706 enum_func = dc->funcs->pEnumDeviceFonts;
707 GDI_ReleaseObj( hDC );
709 if (enum_func)
711 NEWTEXTMETRICEX16 tm16;
712 ENUMLOGFONTEX16 lf16;
713 fontEnum16 fe16;
714 LOGFONTW lfW;
715 FONT_LogFont16ToW(plf, &lfW);
717 fe16.lpLogFontParam = plf;
718 fe16.lpEnumFunc = efproc;
719 fe16.lpData = lParam;
720 fe16.lpTextMetric = &tm16;
721 fe16.lpLogFont = &lf16;
722 fe16.segTextMetric = MapLS( &tm16 );
723 fe16.segLogFont = MapLS( &lf16 );
725 retVal = enum_func( hDC, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
726 UnMapLS( fe16.segTextMetric );
727 UnMapLS( fe16.segLogFont );
729 return retVal;
732 /***********************************************************************
733 * FONT_EnumFontFamiliesEx
735 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
736 FONTENUMPROCEXW efproc,
737 LPARAM lParam, DWORD dwUnicode)
739 BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
740 INT ret = 1;
741 DC *dc = DC_GetDCPtr( hDC );
742 fontEnum32 fe32;
743 BOOL enum_gdi_fonts;
745 if (!dc) return 0;
747 fe32.lpLogFontParam = plf;
748 fe32.lpEnumFunc = efproc;
749 fe32.lpData = lParam;
750 fe32.dwFlags = dwUnicode;
752 enum_func = dc->funcs->pEnumDeviceFonts;
753 GDI_ReleaseObj( hDC );
754 enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
756 if (!enum_func && !enum_gdi_fonts) return 0;
758 if (enum_gdi_fonts)
759 ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
760 if (ret && enum_func)
761 ret = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 );
762 return ret;
765 /***********************************************************************
766 * EnumFontFamiliesExW (GDI32.@)
768 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
769 FONTENUMPROCEXW efproc,
770 LPARAM lParam, DWORD dwFlags )
772 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
775 /***********************************************************************
776 * EnumFontFamiliesExA (GDI32.@)
778 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
779 FONTENUMPROCEXA efproc,
780 LPARAM lParam, DWORD dwFlags)
782 LOGFONTW lfW;
783 FONT_LogFontAToW( plf, &lfW );
785 return FONT_EnumFontFamiliesEx( hDC, &lfW,
786 (FONTENUMPROCEXW)efproc, lParam, 0);
789 /***********************************************************************
790 * EnumFontFamilies (GDI.330)
792 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
793 FONTENUMPROC16 efproc, LPARAM lpData )
795 LOGFONT16 lf;
797 lf.lfCharSet = DEFAULT_CHARSET;
798 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
799 else lf.lfFaceName[0] = '\0';
801 return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
804 /***********************************************************************
805 * EnumFontFamiliesA (GDI32.@)
807 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
808 FONTENUMPROCA efproc, LPARAM lpData )
810 LOGFONTA lf;
812 lf.lfCharSet = DEFAULT_CHARSET;
813 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
814 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
816 return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
819 /***********************************************************************
820 * EnumFontFamiliesW (GDI32.@)
822 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
823 FONTENUMPROCW efproc, LPARAM lpData )
825 LOGFONTW lf;
827 lf.lfCharSet = DEFAULT_CHARSET;
828 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
829 else lf.lfFaceName[0] = 0;
831 return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
834 /***********************************************************************
835 * EnumFonts (GDI.70)
837 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
838 LPARAM lpData )
840 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
843 /***********************************************************************
844 * EnumFontsA (GDI32.@)
846 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
847 LPARAM lpData )
849 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
852 /***********************************************************************
853 * EnumFontsW (GDI32.@)
855 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
856 LPARAM lpData )
858 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
862 /***********************************************************************
863 * GetTextCharacterExtra (GDI.89)
865 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
867 return (INT16)GetTextCharacterExtra( hdc );
871 /***********************************************************************
872 * GetTextCharacterExtra (GDI32.@)
874 INT WINAPI GetTextCharacterExtra( HDC hdc )
876 INT ret;
877 DC *dc = DC_GetDCPtr( hdc );
878 if (!dc) return 0;
879 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
880 / dc->vportExtX );
881 GDI_ReleaseObj( hdc );
882 return ret;
886 /***********************************************************************
887 * SetTextCharacterExtra (GDI.8)
889 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
891 return (INT16)SetTextCharacterExtra( hdc, extra );
895 /***********************************************************************
896 * SetTextCharacterExtra (GDI32.@)
898 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
900 INT prev;
901 DC * dc = DC_GetDCPtr( hdc );
902 if (!dc) return 0;
903 if (dc->funcs->pSetTextCharacterExtra)
904 prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
905 else
907 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
908 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
909 dc->charExtra = abs(extra);
911 GDI_ReleaseObj( hdc );
912 return prev;
916 /***********************************************************************
917 * SetTextJustification (GDI.10)
919 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
921 return SetTextJustification( hdc, extra, breaks );
925 /***********************************************************************
926 * SetTextJustification (GDI32.@)
928 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
930 BOOL ret = TRUE;
931 DC * dc = DC_GetDCPtr( hdc );
932 if (!dc) return FALSE;
933 if (dc->funcs->pSetTextJustification)
934 ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
935 else
937 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
938 if (!extra) breaks = 0;
939 dc->breakTotalExtra = extra;
940 dc->breakCount = breaks;
941 if (breaks)
943 dc->breakExtra = extra / breaks;
944 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
946 else
948 dc->breakExtra = 0;
949 dc->breakRem = 0;
952 GDI_ReleaseObj( hdc );
953 return ret;
957 /***********************************************************************
958 * GetTextFace (GDI.92)
960 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
962 return GetTextFaceA(hdc,count,name);
965 /***********************************************************************
966 * GetTextFaceA (GDI32.@)
968 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
970 INT res = GetTextFaceW(hdc, 0, NULL);
971 LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
972 GetTextFaceW( hdc, res, nameW );
974 if (name)
975 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
976 NULL, NULL);
977 else
978 res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
979 HeapFree( GetProcessHeap(), 0, nameW );
980 return res;
983 /***********************************************************************
984 * GetTextFaceW (GDI32.@)
986 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
988 FONTOBJ *font;
989 INT ret = 0;
991 DC * dc = DC_GetDCPtr( hdc );
992 if (!dc) return 0;
994 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
996 if (name)
998 lstrcpynW( name, font->logfont.lfFaceName, count );
999 ret = strlenW(name);
1001 else ret = strlenW(font->logfont.lfFaceName) + 1;
1002 GDI_ReleaseObj( dc->hFont );
1004 GDI_ReleaseObj( hdc );
1005 return ret;
1009 /***********************************************************************
1010 * GetTextExtent (GDI.91)
1012 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1014 SIZE16 size;
1015 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1016 return MAKELONG( size.cx, size.cy );
1020 /***********************************************************************
1021 * GetTextExtentPoint (GDI.471)
1023 * FIXME: Should this have a bug for compatibility?
1024 * Original Windows versions of GetTextExtentPoint{A,W} have documented
1025 * bugs (-> MSDN KB q147647.txt).
1027 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1028 LPSIZE16 size )
1030 SIZE size32;
1031 BOOL ret;
1032 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1033 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1034 size->cx = size32.cx;
1035 size->cy = size32.cy;
1036 return (BOOL16)ret;
1040 /***********************************************************************
1041 * GetTextExtentPoint32A (GDI32.@)
1043 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1044 LPSIZE size )
1046 BOOL ret = FALSE;
1047 INT wlen;
1048 LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1050 if (p) {
1051 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1052 HeapFree( GetProcessHeap(), 0, p );
1055 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1056 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1057 return ret;
1061 /***********************************************************************
1062 * GetTextExtentPoint32W [GDI32.@] Computes width/height for a string
1064 * Computes width and height of the specified string.
1066 * RETURNS
1067 * Success: TRUE
1068 * Failure: FALSE
1070 BOOL WINAPI GetTextExtentPoint32W(
1071 HDC hdc, /* [in] Handle of device context */
1072 LPCWSTR str, /* [in] Address of text string */
1073 INT count, /* [in] Number of characters in string */
1074 LPSIZE size) /* [out] Address of structure for string size */
1076 BOOL ret = FALSE;
1077 DC * dc = DC_GetDCPtr( hdc );
1078 if (!dc) return FALSE;
1080 if(dc->gdiFont)
1081 ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1082 else if(dc->funcs->pGetTextExtentPoint)
1083 ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
1085 GDI_ReleaseObj( hdc );
1087 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1088 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1089 return ret;
1093 /***********************************************************************
1094 * GetTextExtentPointA (GDI32.@)
1096 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1097 LPSIZE size )
1099 TRACE("not bug compatible.\n");
1100 return GetTextExtentPoint32A( hdc, str, count, size );
1103 /***********************************************************************
1104 * GetTextExtentPointW (GDI32.@)
1106 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1107 LPSIZE size )
1109 TRACE("not bug compatible.\n");
1110 return GetTextExtentPoint32W( hdc, str, count, size );
1114 /***********************************************************************
1115 * GetTextExtentExPointA (GDI32.@)
1117 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1118 INT maxExt, LPINT lpnFit,
1119 LPINT alpDx, LPSIZE size )
1121 BOOL ret;
1122 INT wlen;
1123 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1124 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1125 HeapFree( GetProcessHeap(), 0, p );
1126 return ret;
1130 /***********************************************************************
1131 * GetTextExtentExPointW (GDI32.@)
1133 * Return the size of the string as it would be if it was output properly by
1134 * e.g. TextOut.
1136 * This should include
1137 * - Intercharacter spacing
1138 * - justification spacing (not yet done)
1139 * - kerning? see below
1141 * Kerning. Since kerning would be carried out by the rendering code it should
1142 * be done by the driver. However they don't support it yet. Also I am not
1143 * yet persuaded that (certainly under Win95) any kerning is actually done.
1145 * str: According to MSDN this should be null-terminated. That is not true; a
1146 * null will not terminate it early.
1147 * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1148 * than count. I have seen it be either the size of the full string or
1149 * 1 less than the size of the full string. I have not seen it bear any
1150 * resemblance to the portion that would fit.
1151 * lpnFit: What exactly is fitting? Stupidly, in my opinion, it includes the
1152 * trailing intercharacter spacing and any trailing justification.
1154 * FIXME
1155 * Currently we do this by measuring each character etc. We should do it by
1156 * passing the request to the driver, perhaps by extending the
1157 * pGetTextExtentPoint function to take the alpDx argument. That would avoid
1158 * thinking about kerning issues and rounding issues in the justification.
1161 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1162 INT maxExt, LPINT lpnFit,
1163 LPINT alpDx, LPSIZE size )
1165 int index, nFit, extent;
1166 SIZE tSize;
1167 BOOL ret = FALSE;
1169 TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1171 size->cx = size->cy = nFit = extent = 0;
1172 for(index = 0; index < count; index++)
1174 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1175 /* GetTextExtentPoint includes intercharacter spacing. */
1176 /* FIXME - justification needs doing yet. Remember that the base
1177 * data will not be in logical coordinates.
1179 extent += tSize.cx;
1180 if( !lpnFit || extent <= maxExt )
1181 /* It is allowed to be equal. */
1183 nFit++;
1184 if( alpDx ) alpDx[index] = extent;
1186 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1187 str++;
1189 size->cx = extent;
1190 if(lpnFit) *lpnFit = nFit;
1191 ret = TRUE;
1193 TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1195 done:
1196 return ret;
1199 /***********************************************************************
1200 * GetTextMetrics (GDI.93)
1202 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1204 TEXTMETRICW tm32;
1206 if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1207 FONT_TextMetricWTo16( &tm32, metrics );
1208 return TRUE;
1212 /***********************************************************************
1213 * GetTextMetricsA (GDI32.@)
1215 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1217 TEXTMETRICW tm32;
1219 if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1220 FONT_TextMetricWToA( &tm32, metrics );
1221 return TRUE;
1224 /***********************************************************************
1225 * GetTextMetricsW (GDI32.@)
1227 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1229 BOOL ret = FALSE;
1230 DC * dc = DC_GetDCPtr( hdc );
1231 if (!dc) return FALSE;
1233 if (dc->gdiFont)
1234 ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1235 else if (dc->funcs->pGetTextMetrics)
1236 ret = dc->funcs->pGetTextMetrics( dc, metrics );
1238 if (ret)
1240 /* device layer returns values in device units
1241 * therefore we have to convert them to logical */
1243 #define WDPTOLP(x) ((x<0)? \
1244 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1245 (abs((x)*dc->wndExtX/dc->vportExtX)))
1246 #define HDPTOLP(y) ((y<0)? \
1247 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1248 (abs((y)*dc->wndExtY/dc->vportExtY)))
1250 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1251 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1252 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1253 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1254 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1255 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1256 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1257 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1258 ret = TRUE;
1260 TRACE("text metrics:\n"
1261 " Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1262 " Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1263 " UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1264 " StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1265 " PitchAndFamily = %02x\n"
1266 " --------------------\n"
1267 " InternalLeading = %li\n"
1268 " Ascent = %li\n"
1269 " Descent = %li\n"
1270 " Height = %li\n",
1271 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1272 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1273 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1274 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1275 metrics->tmPitchAndFamily,
1276 metrics->tmInternalLeading,
1277 metrics->tmAscent,
1278 metrics->tmDescent,
1279 metrics->tmHeight );
1281 GDI_ReleaseObj( hdc );
1282 return ret;
1286 /***********************************************************************
1287 * GetOutlineTextMetrics [GDI.308] Gets metrics for TrueType fonts.
1289 * NOTES
1290 * lpOTM should be LPOUTLINETEXTMETRIC
1292 * RETURNS
1293 * Success: Non-zero or size of required buffer
1294 * Failure: 0
1296 UINT16 WINAPI GetOutlineTextMetrics16(
1297 HDC16 hdc, /* [in] Handle of device context */
1298 UINT16 cbData, /* [in] Size of metric data array */
1299 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1301 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1302 return 0;
1306 /***********************************************************************
1307 * GetOutlineTextMetricsA (GDI32.@)
1308 * Gets metrics for TrueType fonts.
1311 * RETURNS
1312 * Success: Non-zero or size of required buffer
1313 * Failure: 0
1315 UINT WINAPI GetOutlineTextMetricsA(
1316 HDC hdc, /* [in] Handle of device context */
1317 UINT cbData, /* [in] Size of metric data array */
1318 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1320 char buf[512], *ptr;
1321 UINT ret, needed;
1322 OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1323 INT left, len;
1325 if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1326 if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1327 return 0;
1328 lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1329 GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1332 needed = sizeof(OUTLINETEXTMETRICA);
1333 if(lpOTMW->otmpFamilyName)
1334 needed += WideCharToMultiByte(CP_ACP, 0,
1335 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1336 NULL, 0, NULL, NULL);
1337 if(lpOTMW->otmpFaceName)
1338 needed += WideCharToMultiByte(CP_ACP, 0,
1339 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1340 NULL, 0, NULL, NULL);
1341 if(lpOTMW->otmpStyleName)
1342 needed += WideCharToMultiByte(CP_ACP, 0,
1343 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1344 NULL, 0, NULL, NULL);
1345 if(lpOTMW->otmpFullName)
1346 needed += WideCharToMultiByte(CP_ACP, 0,
1347 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1348 NULL, 0, NULL, NULL);
1350 if(!lpOTM) {
1351 ret = needed;
1352 goto end;
1355 if(needed > cbData) {
1356 ret = 0;
1357 goto end;
1361 lpOTM->otmSize = needed;
1362 FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1363 lpOTM->otmFiller = 0;
1364 lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1365 lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1366 lpOTM->otmfsType = lpOTMW->otmfsType;
1367 lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1368 lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1369 lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1370 lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1371 lpOTM->otmAscent = lpOTMW->otmAscent;
1372 lpOTM->otmDescent = lpOTMW->otmDescent;
1373 lpOTM->otmLineGap = lpOTMW->otmLineGap;
1374 lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1375 lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1376 lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1377 lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1378 lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1379 lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1380 lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1381 lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1382 lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1383 lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1384 lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1385 lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1386 lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1387 lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1388 lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1391 ptr = (char*)(lpOTM + 1);
1392 left = needed - sizeof(*lpOTM);
1394 if(lpOTMW->otmpFamilyName) {
1395 lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1396 len = WideCharToMultiByte(CP_ACP, 0,
1397 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1398 ptr, left, NULL, NULL);
1399 left -= len;
1400 ptr += len;
1401 } else
1402 lpOTM->otmpFamilyName = 0;
1404 if(lpOTMW->otmpFaceName) {
1405 lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1406 len = WideCharToMultiByte(CP_ACP, 0,
1407 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1408 ptr, left, NULL, NULL);
1409 left -= len;
1410 ptr += len;
1411 } else
1412 lpOTM->otmpFaceName = 0;
1414 if(lpOTMW->otmpStyleName) {
1415 lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1416 len = WideCharToMultiByte(CP_ACP, 0,
1417 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1418 ptr, left, NULL, NULL);
1419 left -= len;
1420 ptr += len;
1421 } else
1422 lpOTM->otmpStyleName = 0;
1424 if(lpOTMW->otmpFullName) {
1425 lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1426 len = WideCharToMultiByte(CP_ACP, 0,
1427 (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1428 ptr, left, NULL, NULL);
1429 left -= len;
1430 } else
1431 lpOTM->otmpFullName = 0;
1433 assert(left == 0);
1435 ret = needed;
1437 end:
1438 if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1439 HeapFree(GetProcessHeap(), 0, lpOTMW);
1441 return ret;
1445 /***********************************************************************
1446 * GetOutlineTextMetricsW [GDI32.@]
1448 UINT WINAPI GetOutlineTextMetricsW(
1449 HDC hdc, /* [in] Handle of device context */
1450 UINT cbData, /* [in] Size of metric data array */
1451 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1453 DC *dc = DC_GetDCPtr( hdc );
1454 UINT ret;
1456 TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1457 if(!dc) return 0;
1459 if(dc->gdiFont)
1460 ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1462 else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1463 but really this should just be a return 0. */
1465 ret = sizeof(*lpOTM);
1466 if (lpOTM) {
1467 if(cbData < ret)
1468 ret = 0;
1469 else {
1470 memset(lpOTM, 0, ret);
1471 lpOTM->otmSize = sizeof(*lpOTM);
1472 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1474 Further fill of the structure not implemented,
1475 Needs real values for the structure members
1480 GDI_ReleaseObj(hdc);
1481 return ret;
1485 /***********************************************************************
1486 * GetCharWidth (GDI.350)
1488 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1489 LPINT16 buffer )
1491 BOOL retVal = FALSE;
1493 if( firstChar != lastChar )
1495 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1496 sizeof(INT)*(1 + (lastChar - firstChar)));
1497 if( buf32 )
1499 LPINT obuf32 = buf32;
1500 int i;
1502 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1503 if (retVal)
1505 for (i = firstChar; i <= lastChar; i++)
1506 *buffer++ = *buf32++;
1508 HeapFree(GetProcessHeap(), 0, obuf32);
1511 else /* happens quite often to warrant a special treatment */
1513 INT chWidth;
1514 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1515 *buffer = chWidth;
1517 return retVal;
1521 /***********************************************************************
1522 * GetCharWidthW (GDI32.@)
1523 * GetCharWidth32W (GDI32.@)
1525 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1526 LPINT buffer )
1528 UINT i, extra;
1529 BOOL ret = FALSE;
1530 DC * dc = DC_GetDCPtr( hdc );
1531 if (!dc) return FALSE;
1533 if (dc->gdiFont)
1534 ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1535 else if (dc->funcs->pGetCharWidth)
1536 ret = dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer);
1538 if (ret)
1540 /* convert device units to logical */
1542 extra = dc->vportExtX >> 1;
1543 for( i = firstChar; i <= lastChar; i++, buffer++ )
1544 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1545 ret = TRUE;
1547 GDI_ReleaseObj( hdc );
1548 return ret;
1552 /***********************************************************************
1553 * GetCharWidthA (GDI32.@)
1554 * GetCharWidth32A (GDI32.@)
1556 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1557 LPINT buffer )
1559 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1560 LPSTR str;
1561 LPWSTR wstr;
1562 BOOL ret = TRUE;
1564 if(count <= 0) return FALSE;
1566 str = HeapAlloc(GetProcessHeap(), 0, count);
1567 for(i = 0; i < count; i++)
1568 str[i] = (BYTE)(firstChar + i);
1570 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1572 for(i = 0; i < wlen; i++)
1574 if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1576 ret = FALSE;
1577 break;
1579 buffer++;
1582 HeapFree(GetProcessHeap(), 0, str);
1583 HeapFree(GetProcessHeap(), 0, wstr);
1585 return ret;
1589 /* FIXME: all following APIs ******************************************/
1592 /***********************************************************************
1593 * SetMapperFlags (GDI.349)
1595 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1597 return SetMapperFlags( hDC, dwFlag );
1601 /***********************************************************************
1602 * SetMapperFlags (GDI32.@)
1604 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1606 DC *dc = DC_GetDCPtr( hDC );
1607 DWORD ret = 0;
1608 if(!dc) return 0;
1609 if(dc->funcs->pSetMapperFlags)
1610 ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1611 else
1612 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1613 GDI_ReleaseObj( hDC );
1614 return ret;
1617 /***********************************************************************
1618 * GetAspectRatioFilterEx (GDI.486)
1620 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1622 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1623 return FALSE;
1626 /***********************************************************************
1627 * GetAspectRatioFilterEx (GDI32.@)
1629 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1631 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1632 return FALSE;
1635 /***********************************************************************
1636 * GetCharABCWidths (GDI.307)
1638 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1639 LPABC16 abc )
1641 LPABC abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1642 int i;
1644 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1645 HeapFree(GetProcessHeap(),0,abc32);
1646 return FALSE;
1649 for (i=firstChar;i<=lastChar;i++) {
1650 abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1651 abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1652 abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1654 HeapFree(GetProcessHeap(),0,abc32);
1655 return TRUE;
1659 /***********************************************************************
1660 * GetCharABCWidthsA (GDI32.@)
1662 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1663 LPABC abc )
1665 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1666 LPSTR str;
1667 LPWSTR wstr;
1668 BOOL ret = TRUE;
1670 if(count <= 0) return FALSE;
1672 str = HeapAlloc(GetProcessHeap(), 0, count);
1673 for(i = 0; i < count; i++)
1674 str[i] = (BYTE)(firstChar + i);
1676 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1678 for(i = 0; i < wlen; i++)
1680 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1682 ret = FALSE;
1683 break;
1685 abc++;
1688 HeapFree(GetProcessHeap(), 0, str);
1689 HeapFree(GetProcessHeap(), 0, wstr);
1691 return ret;
1695 /******************************************************************************
1696 * GetCharABCWidthsW [GDI32.@] Retrieves widths of characters in range
1698 * PARAMS
1699 * hdc [I] Handle of device context
1700 * firstChar [I] First character in range to query
1701 * lastChar [I] Last character in range to query
1702 * abc [O] Address of character-width structure
1704 * NOTES
1705 * Only works with TrueType fonts
1707 * RETURNS
1708 * Success: TRUE
1709 * Failure: FALSE
1711 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1712 LPABC abc )
1714 DC *dc = DC_GetDCPtr(hdc);
1715 int i;
1716 GLYPHMETRICS gm;
1717 BOOL ret = FALSE;
1719 if(dc->gdiFont) {
1720 for (i=firstChar;i<=lastChar;i++) {
1721 GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1722 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1723 abc[i-firstChar].abcB = gm.gmBlackBoxX;
1724 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1726 ret = TRUE;
1728 GDI_ReleaseObj(hdc);
1729 return ret;
1733 /***********************************************************************
1734 * GetGlyphOutline (GDI.309)
1736 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1737 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1738 LPVOID lpBuffer, const MAT2 *lpmat2 )
1740 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1741 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1742 return (DWORD)-1; /* failure */
1746 /***********************************************************************
1747 * GetGlyphOutlineA (GDI32.@)
1749 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1750 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1751 LPVOID lpBuffer, const MAT2 *lpmat2 )
1753 LPWSTR p = NULL;
1754 DWORD ret;
1755 UINT c;
1757 if(!(fuFormat & GGO_GLYPH_INDEX)) {
1758 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1759 c = p[0];
1760 } else
1761 c = uChar;
1762 ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1763 lpmat2);
1764 if(p)
1765 HeapFree(GetProcessHeap(), 0, p);
1766 return ret;
1769 /***********************************************************************
1770 * GetGlyphOutlineW (GDI32.@)
1772 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1773 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1774 LPVOID lpBuffer, const MAT2 *lpmat2 )
1776 DC *dc = DC_GetDCPtr(hdc);
1777 DWORD ret;
1779 TRACE("(%04x, '%c', %04x, %p, %ld, %p, %p)\n",
1780 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1782 if(!dc) return GDI_ERROR;
1784 if(dc->gdiFont)
1785 ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1786 cbBuffer, lpBuffer, lpmat2);
1787 else
1788 ret = GDI_ERROR;
1790 GDI_ReleaseObj(hdc);
1791 return ret;
1794 /***********************************************************************
1795 * CreateScalableFontResource (GDI.310)
1797 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1798 LPCSTR lpszResourceFile,
1799 LPCSTR fontFile, LPCSTR path )
1801 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1802 fontFile, path );
1805 /***********************************************************************
1806 * CreateScalableFontResourceA (GDI32.@)
1808 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1809 LPCSTR lpszResourceFile,
1810 LPCSTR lpszFontFile,
1811 LPCSTR lpszCurrentPath )
1813 /* fHidden=1 - only visible for the calling app, read-only, not
1814 * enumbered with EnumFonts/EnumFontFamilies
1815 * lpszCurrentPath can be NULL
1817 FIXME("(%ld,%s,%s,%s): stub\n",
1818 fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1819 debugstr_a(lpszCurrentPath) );
1820 return FALSE; /* create failed */
1823 /***********************************************************************
1824 * CreateScalableFontResourceW (GDI32.@)
1826 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1827 LPCWSTR lpszResourceFile,
1828 LPCWSTR lpszFontFile,
1829 LPCWSTR lpszCurrentPath )
1831 FIXME("(%ld,%p,%p,%p): stub\n",
1832 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1833 return FALSE; /* create failed */
1837 /*************************************************************************
1838 * GetRasterizerCaps (GDI.313)
1840 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1842 return GetRasterizerCaps( lprs, cbNumBytes );
1846 /*************************************************************************
1847 * GetRasterizerCaps (GDI32.@)
1849 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1851 lprs->nSize = sizeof(RASTERIZER_STATUS);
1852 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1853 lprs->nLanguageID = 0;
1854 return TRUE;
1858 /*************************************************************************
1859 * GetKerningPairs (GDI.332)
1862 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1863 LPKERNINGPAIR16 lpKerningPairs )
1865 /* At this time kerning is ignored (set to 0) */
1866 int i;
1867 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1868 if (lpKerningPairs)
1869 for (i = 0; i < cPairs; i++)
1870 lpKerningPairs[i].iKernAmount = 0;
1871 /* FIXME: Should this function call SetLastError (0)? This is yet another
1872 * Microsoft function that can return 0 on success or failure
1874 return 0;
1879 /*************************************************************************
1880 * GetKerningPairsA (GDI32.@)
1882 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1883 LPKERNINGPAIR lpKerningPairs )
1885 int i;
1886 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1887 for (i = 0; i < cPairs; i++)
1888 lpKerningPairs[i].iKernAmount = 0;
1889 return 0;
1893 /*************************************************************************
1894 * GetKerningPairsW (GDI32.@)
1896 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1897 LPKERNINGPAIR lpKerningPairs )
1899 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1902 /*************************************************************************
1903 * TranslateCharsetInfo [GDI32.@]
1904 * TranslateCharsetInfo [USER32.@]
1906 * Fills a CHARSETINFO structure for a character set, code page, or
1907 * font. This allows making the correspondance between different labelings
1908 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1909 * of the same encoding.
1911 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1912 * only one codepage should be set in *lpSrc.
1914 * RETURNS
1915 * TRUE on success, FALSE on failure.
1918 BOOL WINAPI TranslateCharsetInfo(
1919 LPDWORD lpSrc, /* [in]
1920 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1921 if flags == TCI_SRCCHARSET: a character set value
1922 if flags == TCI_SRCCODEPAGE: a code page value
1924 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1925 DWORD flags /* [in] determines interpretation of lpSrc */
1927 int index = 0;
1928 switch (flags) {
1929 case TCI_SRCFONTSIG:
1930 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1931 break;
1932 case TCI_SRCCODEPAGE:
1933 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1934 break;
1935 case TCI_SRCCHARSET:
1936 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1937 break;
1938 default:
1939 return FALSE;
1941 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1942 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1943 return TRUE;
1946 /*************************************************************************
1947 * GetFontLanguageInfo (GDI32.@)
1949 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1950 /* return value 0 is correct for most cases anyway */
1951 FIXME("(%x):stub!\n", hdc);
1952 return 0;
1955 /*************************************************************************
1956 * GetFontLanguageInfo (GDI.616)
1958 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1959 /* return value 0 is correct for most cases anyway */
1960 FIXME("(%x):stub!\n",hdc);
1961 return 0;
1964 /*************************************************************************
1965 * GetFontData [GDI32.@] Retrieve data for TrueType font
1967 * RETURNS
1969 * success: Number of bytes returned
1970 * failure: GDI_ERROR
1972 * NOTES
1974 * Calls SetLastError()
1977 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1978 LPVOID buffer, DWORD length)
1980 DC *dc = DC_GetDCPtr(hdc);
1981 DWORD ret = GDI_ERROR;
1983 if(!dc) return GDI_ERROR;
1985 if(dc->gdiFont)
1986 ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1988 GDI_ReleaseObj(hdc);
1989 return ret;
1992 /*************************************************************************
1993 * GetFontData [GDI.311]
1996 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1997 LPVOID lpvBuffer, DWORD cbData)
1999 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2002 /*************************************************************************
2003 * GetCharacterPlacementA [GDI32.@]
2005 * NOTES:
2006 * the web browser control of ie4 calls this with dwFlags=0
2008 DWORD WINAPI
2009 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2010 INT nMaxExtent, GCP_RESULTSA *lpResults,
2011 DWORD dwFlags)
2013 DWORD ret=0;
2014 SIZE size;
2016 TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
2017 debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
2019 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
2020 "lpOutString=%p lpGlyphs=%p\n",
2021 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
2022 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
2024 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
2025 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
2026 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2027 if(lpResults->lpClass) FIXME("classes not implemented\n");
2028 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
2030 /* copy will do if the GCP_REORDER flag is not set */
2031 if(lpResults->lpOutString)
2033 lstrcpynA(lpResults->lpOutString, lpString, uCount);
2036 if (lpResults->lpDx)
2038 int i, c;
2039 for (i=0; i<uCount;i++)
2041 if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
2042 lpResults->lpDx[i]= c;
2046 if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
2047 ret = MAKELONG(size.cx, size.cy);
2049 return ret;
2052 /*************************************************************************
2053 * GetCharacterPlacementW [GDI32.@]
2055 DWORD WINAPI
2056 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
2057 INT nMaxExtent, GCP_RESULTSW *lpResults,
2058 DWORD dwFlags)
2060 DWORD ret=0;
2061 SIZE size;
2063 TRACE("%s 0x%08x 0x%08x 0x%08lx:partial stub!\n",
2064 debugstr_w(lpString), uCount, nMaxExtent, dwFlags);
2066 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
2067 "lpOutString=%p lpGlyphs=%p\n",
2068 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
2069 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
2071 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
2072 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
2073 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
2074 if(lpResults->lpClass) FIXME("classes not implemented\n");
2075 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
2077 /* copy will do if the GCP_REORDER flag is not set */
2078 if(lpResults->lpOutString)
2080 lstrcpynW(lpResults->lpOutString, lpString, uCount);
2083 if (lpResults->lpDx)
2085 int i, c;
2086 for (i=0; i<uCount;i++)
2088 if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2089 lpResults->lpDx[i]= c;
2093 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2094 ret = MAKELONG(size.cx, size.cy);
2096 return ret;
2099 /*************************************************************************
2100 * GetCharABCWidthsFloatA [GDI32.@]
2102 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2103 LPABCFLOAT lpABCF)
2105 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2106 return 0;
2109 /*************************************************************************
2110 * GetCharABCWidthsFloatW [GDI32.@]
2112 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2113 UINT iLastChar, LPABCFLOAT lpABCF)
2115 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2116 return 0;
2119 /*************************************************************************
2120 * GetCharWidthFloatA [GDI32.@]
2122 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2123 UINT iLastChar, PFLOAT pxBuffer)
2125 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2126 return 0;
2129 /*************************************************************************
2130 * GetCharWidthFloatW [GDI32.@]
2132 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2133 UINT iLastChar, PFLOAT pxBuffer)
2135 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2136 return 0;
2140 /***********************************************************************
2142 * Font Resource API *
2144 ***********************************************************************/
2145 /***********************************************************************
2146 * AddFontResource (GDI.119)
2148 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2150 * FIXME: Load header and find the best-matching font in the fontList;
2151 * fixup dfPoints if all metrics are identical, otherwise create
2152 * new fontAlias. When soft font support is ready this will
2153 * simply create a new fontResource ('filename' will go into
2154 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
2155 * flag set.
2157 INT16 WINAPI AddFontResource16( LPCSTR filename )
2159 return AddFontResourceA( filename );
2163 /***********************************************************************
2164 * AddFontResourceA (GDI32.@)
2166 INT WINAPI AddFontResourceA( LPCSTR str )
2168 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2169 "this font manually.\n", debugres_a(str));
2170 return 1;
2174 /***********************************************************************
2175 * AddFontResourceW (GDI32.@)
2177 INT WINAPI AddFontResourceW( LPCWSTR str )
2179 FIXME("(%s): stub! Read the Wine User Guide on how to install "
2180 "this font manually.\n", debugres_w(str));
2181 return 1;
2184 /***********************************************************************
2185 * RemoveFontResource (GDI.136)
2187 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2189 FIXME("(%s): stub\n", debugres_a(str));
2190 return TRUE;
2194 /***********************************************************************
2195 * RemoveFontResourceA (GDI32.@)
2197 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2199 /* This is how it should look like */
2201 fontResource** ppfr;
2202 BOOL32 retVal = FALSE;
2204 EnterCriticalSection( &crtsc_fonts_X11 );
2205 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2206 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2208 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2209 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2211 if( (*ppfr)->fo_count )
2212 (*ppfr)->fr_flags |= FR_REMOVED;
2213 else
2214 XFONT_RemoveFontResource( ppfr );
2216 retVal = TRUE;
2218 LeaveCriticalSection( &crtsc_fonts_X11 );
2219 return retVal;
2221 FIXME("(%s): stub\n", debugres_a(str));
2222 return TRUE;
2226 /***********************************************************************
2227 * RemoveFontResourceW (GDI32.@)
2229 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2231 FIXME("(%s): stub\n", debugres_w(str) );
2232 return TRUE;