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