Use SendNotifyMessage() for WM_SYNCPAINT.
[wine.git] / objects / font.c
blob96714854607d0bfaddbc0b19fa79eefbda66eddc
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
6 */
8 #include <stdlib.h>
9 #include <string.h>
10 #include "winerror.h"
11 #include "winnls.h"
12 #include "font.h"
13 #include "heap.h"
14 #include "metafile.h"
15 #include "options.h"
16 #include "debugtools.h"
17 #include "gdi.h"
19 DEFAULT_DEBUG_CHANNEL(font);
20 DECLARE_DEBUG_CHANNEL(gdi);
22 #define ENUM_UNICODE 0x00000001
24 typedef struct
26 LPLOGFONT16 lpLogFontParam;
27 FONTENUMPROCEX16 lpEnumFunc;
28 LPARAM lpData;
30 LPNEWTEXTMETRICEX16 lpTextMetric;
31 LPENUMLOGFONTEX16 lpLogFont;
32 SEGPTR segTextMetric;
33 SEGPTR segLogFont;
34 } fontEnum16;
36 typedef struct
38 LPLOGFONTW lpLogFontParam;
39 FONTENUMPROCEXW lpEnumFunc;
40 LPARAM lpData;
42 LPNEWTEXTMETRICEXW lpTextMetric;
43 LPENUMLOGFONTEXW lpLogFont;
44 DWORD dwFlags;
45 } fontEnum32;
48 * For TranslateCharsetInfo
50 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
51 #define MAXTCIINDEX 32
52 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
53 /* ANSI */
54 { ANSI_CHARSET, 1252, FS(0)},
55 { EASTEUROPE_CHARSET, 1250, FS(1)},
56 { RUSSIAN_CHARSET, 1251, FS(2)},
57 { GREEK_CHARSET, 1253, FS(3)},
58 { TURKISH_CHARSET, 1254, FS(4)},
59 { HEBREW_CHARSET, 1255, FS(5)},
60 { ARABIC_CHARSET, 1256, FS(6)},
61 { BALTIC_CHARSET, 1257, FS(7)},
62 /* reserved by ANSI */
63 { DEFAULT_CHARSET, 0, FS(0)},
64 { DEFAULT_CHARSET, 0, FS(0)},
65 { DEFAULT_CHARSET, 0, FS(0)},
66 { DEFAULT_CHARSET, 0, FS(0)},
67 { DEFAULT_CHARSET, 0, FS(0)},
68 { DEFAULT_CHARSET, 0, FS(0)},
69 { DEFAULT_CHARSET, 0, FS(0)},
70 { DEFAULT_CHARSET, 0, FS(0)},
71 /* ANSI and OEM */
72 { THAI_CHARSET, 874, FS(16)},
73 { SHIFTJIS_CHARSET, 932, FS(17)},
74 { GB2312_CHARSET, 936, FS(18)},
75 { HANGEUL_CHARSET, 949, FS(19)},
76 { CHINESEBIG5_CHARSET, 950, FS(20)},
77 { JOHAB_CHARSET, 1361, FS(21)},
78 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
84 { DEFAULT_CHARSET, 0, FS(0)},
85 { DEFAULT_CHARSET, 0, FS(0)},
86 { DEFAULT_CHARSET, 0, FS(0)},
87 /* reserved for system */
88 { DEFAULT_CHARSET, 0, FS(0)},
89 { DEFAULT_CHARSET, 0, FS(0)},
92 /***********************************************************************
93 * LOGFONT conversion functions.
95 void FONT_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
97 font16->lfHeight = font32->lfHeight;
98 font16->lfWidth = font32->lfWidth;
99 font16->lfEscapement = font32->lfEscapement;
100 font16->lfOrientation = font32->lfOrientation;
101 font16->lfWeight = font32->lfWeight;
102 font16->lfItalic = font32->lfItalic;
103 font16->lfUnderline = font32->lfUnderline;
104 font16->lfStrikeOut = font32->lfStrikeOut;
105 font16->lfCharSet = font32->lfCharSet;
106 font16->lfOutPrecision = font32->lfOutPrecision;
107 font16->lfClipPrecision = font32->lfClipPrecision;
108 font16->lfQuality = font32->lfQuality;
109 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
110 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
113 void FONT_LogFont32WTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
115 font16->lfHeight = font32->lfHeight;
116 font16->lfWidth = font32->lfWidth;
117 font16->lfEscapement = font32->lfEscapement;
118 font16->lfOrientation = font32->lfOrientation;
119 font16->lfWeight = font32->lfWeight;
120 font16->lfItalic = font32->lfItalic;
121 font16->lfUnderline = font32->lfUnderline;
122 font16->lfStrikeOut = font32->lfStrikeOut;
123 font16->lfCharSet = font32->lfCharSet;
124 font16->lfOutPrecision = font32->lfOutPrecision;
125 font16->lfClipPrecision = font32->lfClipPrecision;
126 font16->lfQuality = font32->lfQuality;
127 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
128 WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
129 font16->lfFaceName, LF_FACESIZE, NULL, NULL );
130 font16->lfFaceName[LF_FACESIZE-1] = 0;
133 void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONTA font32 )
135 font32->lfHeight = font16->lfHeight;
136 font32->lfWidth = font16->lfWidth;
137 font32->lfEscapement = font16->lfEscapement;
138 font32->lfOrientation = font16->lfOrientation;
139 font32->lfWeight = font16->lfWeight;
140 font32->lfItalic = font16->lfItalic;
141 font32->lfUnderline = font16->lfUnderline;
142 font32->lfStrikeOut = font16->lfStrikeOut;
143 font32->lfCharSet = font16->lfCharSet;
144 font32->lfOutPrecision = font16->lfOutPrecision;
145 font32->lfClipPrecision = font16->lfClipPrecision;
146 font32->lfQuality = font16->lfQuality;
147 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
148 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
151 void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONTW font32 )
153 font32->lfHeight = font16->lfHeight;
154 font32->lfWidth = font16->lfWidth;
155 font32->lfEscapement = font16->lfEscapement;
156 font32->lfOrientation = font16->lfOrientation;
157 font32->lfWeight = font16->lfWeight;
158 font32->lfItalic = font16->lfItalic;
159 font32->lfUnderline = font16->lfUnderline;
160 font32->lfStrikeOut = font16->lfStrikeOut;
161 font32->lfCharSet = font16->lfCharSet;
162 font32->lfOutPrecision = font16->lfOutPrecision;
163 font32->lfClipPrecision = font16->lfClipPrecision;
164 font32->lfQuality = font16->lfQuality;
165 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
166 MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
167 font32->lfFaceName[LF_FACESIZE-1] = 0;
170 void FONT_EnumLogFontEx16To32A( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXA font32 )
172 FONT_LogFont16To32A( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
173 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
174 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
175 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
178 void FONT_EnumLogFontEx16To32W( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXW font32 )
180 FONT_LogFont16To32W( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
182 MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
183 font32->elfFullName[LF_FULLFACESIZE-1] = 0;
184 MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
185 font32->elfStyle[LF_FACESIZE-1] = 0;
186 MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
187 font32->elfScript[LF_FACESIZE-1] = 0;
190 /***********************************************************************
191 * TEXTMETRIC conversion functions.
193 void FONT_TextMetric32Ato16(const LPTEXTMETRICA ptm32, LPTEXTMETRIC16 ptm16 )
195 ptm16->tmHeight = ptm32->tmHeight;
196 ptm16->tmAscent = ptm32->tmAscent;
197 ptm16->tmDescent = ptm32->tmDescent;
198 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
199 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
200 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
201 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
202 ptm16->tmWeight = ptm32->tmWeight;
203 ptm16->tmOverhang = ptm32->tmOverhang;
204 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
205 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
206 ptm16->tmFirstChar = ptm32->tmFirstChar;
207 ptm16->tmLastChar = ptm32->tmLastChar;
208 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
209 ptm16->tmBreakChar = ptm32->tmBreakChar;
210 ptm16->tmItalic = ptm32->tmItalic;
211 ptm16->tmUnderlined = ptm32->tmUnderlined;
212 ptm16->tmStruckOut = ptm32->tmStruckOut;
213 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
214 ptm16->tmCharSet = ptm32->tmCharSet;
217 void FONT_TextMetric32Wto16(const LPTEXTMETRICW ptm32, LPTEXTMETRIC16 ptm16 )
219 ptm16->tmHeight = ptm32->tmHeight;
220 ptm16->tmAscent = ptm32->tmAscent;
221 ptm16->tmDescent = ptm32->tmDescent;
222 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
223 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
224 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
225 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
226 ptm16->tmWeight = ptm32->tmWeight;
227 ptm16->tmOverhang = ptm32->tmOverhang;
228 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
229 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
230 ptm16->tmFirstChar = ptm32->tmFirstChar;
231 ptm16->tmLastChar = ptm32->tmLastChar;
232 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
233 ptm16->tmBreakChar = ptm32->tmBreakChar;
234 ptm16->tmItalic = ptm32->tmItalic;
235 ptm16->tmUnderlined = ptm32->tmUnderlined;
236 ptm16->tmStruckOut = ptm32->tmStruckOut;
237 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
238 ptm16->tmCharSet = ptm32->tmCharSet;
241 void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICA ptm32 )
243 ptm32->tmHeight = ptm16->tmHeight;
244 ptm32->tmAscent = ptm16->tmAscent;
245 ptm32->tmDescent = ptm16->tmDescent;
246 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
247 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
248 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
249 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
250 ptm32->tmWeight = ptm16->tmWeight;
251 ptm32->tmOverhang = ptm16->tmOverhang;
252 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
253 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
254 ptm32->tmFirstChar = ptm16->tmFirstChar;
255 ptm32->tmLastChar = ptm16->tmLastChar;
256 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
257 ptm32->tmBreakChar = ptm16->tmBreakChar;
258 ptm32->tmItalic = ptm16->tmItalic;
259 ptm32->tmUnderlined = ptm16->tmUnderlined;
260 ptm32->tmStruckOut = ptm16->tmStruckOut;
261 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
262 ptm32->tmCharSet = ptm16->tmCharSet;
265 void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICW ptm32 )
267 ptm32->tmHeight = ptm16->tmHeight;
268 ptm32->tmAscent = ptm16->tmAscent;
269 ptm32->tmDescent = ptm16->tmDescent;
270 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
271 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
272 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
273 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
274 ptm32->tmWeight = ptm16->tmWeight;
275 ptm32->tmOverhang = ptm16->tmOverhang;
276 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
277 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
278 ptm32->tmFirstChar = ptm16->tmFirstChar;
279 ptm32->tmLastChar = ptm16->tmLastChar;
280 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
281 ptm32->tmBreakChar = ptm16->tmBreakChar;
282 ptm32->tmItalic = ptm16->tmItalic;
283 ptm32->tmUnderlined = ptm16->tmUnderlined;
284 ptm32->tmStruckOut = ptm16->tmStruckOut;
285 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
286 ptm32->tmCharSet = ptm16->tmCharSet;
289 void FONT_TextMetric32Ato32W(const LPTEXTMETRICA ptm32A, LPTEXTMETRICW ptm32W )
291 ptm32W->tmHeight = ptm32A->tmHeight;
292 ptm32W->tmAscent = ptm32A->tmAscent;
293 ptm32W->tmDescent = ptm32A->tmDescent;
294 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
295 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
296 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
297 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
298 ptm32W->tmWeight = ptm32A->tmWeight;
299 ptm32W->tmOverhang = ptm32A->tmOverhang;
300 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
301 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
302 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
303 ptm32W->tmLastChar = ptm32A->tmLastChar;
304 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
305 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
306 ptm32W->tmItalic = ptm32A->tmItalic;
307 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
308 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
309 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
310 ptm32W->tmCharSet = ptm32A->tmCharSet;
313 /***********************************************************************
314 * CreateFontIndirect16 (GDI.57)
316 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
318 HFONT hFont = 0;
320 if (font)
322 FONTOBJ* fontPtr;
323 if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
325 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
327 TRACE("(%i %i %i %i) '%s' %s %s => %04x\n",
328 font->lfHeight, font->lfWidth,
329 font->lfEscapement, font->lfOrientation,
330 font->lfFaceName ? font->lfFaceName : "NULL",
331 font->lfWeight > 400 ? "Bold" : "",
332 font->lfItalic ? "Italic" : "", hFont);
334 if (font->lfEscapement != font->lfOrientation) {
335 /* this should really depend on whether GM_ADVANCED is set */
336 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
337 WARN("orientation angle %f set to "
338 "escapement angle %f for new font %04x\n",
339 font->lfOrientation/10., font->lfEscapement/10., hFont);
341 GDI_ReleaseObj( hFont );
344 else WARN("(NULL) => NULL\n");
346 return hFont;
349 /***********************************************************************
350 * CreateFontIndirectA (GDI32.44)
352 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *font )
354 LOGFONT16 font16;
356 FONT_LogFont32ATo16( font, &font16 );
357 return CreateFontIndirect16( &font16 );
360 /***********************************************************************
361 * CreateFontIndirectW (GDI32.45)
363 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *font )
365 LOGFONT16 font16;
367 FONT_LogFont32WTo16( font, &font16 );
368 return CreateFontIndirect16( &font16 );
371 /***********************************************************************
372 * CreateFont16 (GDI.56)
374 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
375 INT16 weight, BYTE italic, BYTE underline,
376 BYTE strikeout, BYTE charset, BYTE outpres,
377 BYTE clippres, BYTE quality, BYTE pitch,
378 LPCSTR name )
380 LOGFONT16 logfont;
382 TRACE("('%s',%d,%d)\n", (name ? name : "(null)") , height, width);
384 logfont.lfHeight = height;
385 logfont.lfWidth = width;
386 logfont.lfEscapement = esc;
387 logfont.lfOrientation = orient;
388 logfont.lfWeight = weight;
389 logfont.lfItalic = italic;
390 logfont.lfUnderline = underline;
391 logfont.lfStrikeOut = strikeout;
392 logfont.lfCharSet = charset;
393 logfont.lfOutPrecision = outpres;
394 logfont.lfClipPrecision = clippres;
395 logfont.lfQuality = quality;
396 logfont.lfPitchAndFamily = pitch;
398 if (name)
399 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
400 else
401 logfont.lfFaceName[0] = '\0';
403 return CreateFontIndirect16( &logfont );
406 /*************************************************************************
407 * CreateFontA (GDI32.43)
409 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
410 INT orient, INT weight, DWORD italic,
411 DWORD underline, DWORD strikeout, DWORD charset,
412 DWORD outpres, DWORD clippres, DWORD quality,
413 DWORD pitch, LPCSTR name )
415 return (HFONT)CreateFont16( height, width, esc, orient, weight, italic,
416 underline, strikeout, charset, outpres,
417 clippres, quality, pitch, name );
420 /*************************************************************************
421 * CreateFontW (GDI32.46)
423 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
424 INT orient, INT weight, DWORD italic,
425 DWORD underline, DWORD strikeout, DWORD charset,
426 DWORD outpres, DWORD clippres, DWORD quality,
427 DWORD pitch, LPCWSTR name )
429 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
430 HFONT ret = (HFONT)CreateFont16( height, width, esc, orient, weight,
431 italic, underline, strikeout, charset,
432 outpres, clippres, quality, pitch,
433 namea );
434 if (namea) HeapFree( GetProcessHeap(), 0, namea );
435 return ret;
439 /***********************************************************************
440 * FONT_GetObject16
442 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
444 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
445 memcpy( buffer, &font->logfont, count );
446 return count;
449 /***********************************************************************
450 * FONT_GetObjectA
452 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
454 LOGFONTA fnt32;
456 FONT_LogFont16To32A( &font->logfont, &fnt32 );
458 if (count > sizeof(fnt32)) count = sizeof(fnt32);
459 memcpy( buffer, &fnt32, count );
460 return count;
462 /***********************************************************************
463 * FONT_GetObjectW
465 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
467 LOGFONTW fnt32;
469 FONT_LogFont16To32W( &font->logfont, &fnt32 );
471 if (count > sizeof(fnt32)) count = sizeof(fnt32);
472 memcpy( buffer, &fnt32, count );
473 return count;
477 /***********************************************************************
478 * FONT_EnumInstance16
480 * Called by the device driver layer to pass font info
481 * down to the application.
483 static INT FONT_EnumInstance16( LPENUMLOGFONTEX16 plf,
484 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
486 #define pfe ((fontEnum16*)lp)
487 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
488 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
490 memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
491 memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
493 return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
495 #undef pfe
496 return 1;
499 /***********************************************************************
500 * FONT_EnumInstance
502 static INT FONT_EnumInstance( LPENUMLOGFONTEX16 plf,
503 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
505 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
507 #define pfe ((fontEnum32*)lp)
508 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
509 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
511 /* convert font metrics */
513 if( pfe->dwFlags & ENUM_UNICODE )
515 FONT_EnumLogFontEx16To32W( plf, pfe->lpLogFont );
516 FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICW)(pfe->lpTextMetric) );
518 return pfe->lpEnumFunc( pfe->lpLogFont, pfe->lpTextMetric, fType, pfe->lpData );
520 else
522 ENUMLOGFONTEXA logfont;
524 FONT_EnumLogFontEx16To32A( plf, &logfont);
525 FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICA)pfe->lpTextMetric );
527 return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
528 pfe->lpTextMetric, fType, pfe->lpData );
531 #undef pfe
532 return 1;
535 /***********************************************************************
536 * EnumFontFamiliesEx16 (GDI.613)
538 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
539 FONTENUMPROCEX16 efproc, LPARAM lParam,
540 DWORD dwFlags)
542 BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
543 INT16 retVal = 0;
544 DC* dc = DC_GetDCPtr( hDC );
546 if (!dc) return 0;
547 enum_func = dc->funcs->pEnumDeviceFonts;
548 GDI_ReleaseObj( hDC );
550 if (enum_func)
552 LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
553 if( lptm16 )
555 LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
556 if( lplf16 )
558 fontEnum16 fe16;
560 fe16.lpLogFontParam = plf;
561 fe16.lpEnumFunc = efproc;
562 fe16.lpData = lParam;
564 fe16.lpTextMetric = lptm16;
565 fe16.lpLogFont = lplf16;
566 fe16.segTextMetric = SEGPTR_GET(lptm16);
567 fe16.segLogFont = SEGPTR_GET(lplf16);
569 retVal = enum_func( hDC, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
570 SEGPTR_FREE(lplf16);
572 SEGPTR_FREE(lptm16);
575 return retVal;
578 /***********************************************************************
579 * FONT_EnumFontFamiliesEx
581 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc,
582 LPARAM lParam, DWORD dwUnicode)
584 BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
585 INT ret = 0;
586 DC *dc = DC_GetDCPtr( hDC );
588 if (!dc) return 0;
589 enum_func = dc->funcs->pEnumDeviceFonts;
590 GDI_ReleaseObj( hDC );
592 if (enum_func)
594 LOGFONT16 lf16;
595 NEWTEXTMETRICEXW tm32w;
596 ENUMLOGFONTEXW lf32w;
597 fontEnum32 fe32;
599 fe32.lpLogFontParam = plf;
600 fe32.lpEnumFunc = efproc;
601 fe32.lpData = lParam;
603 fe32.lpTextMetric = &tm32w;
604 fe32.lpLogFont = &lf32w;
605 fe32.dwFlags = dwUnicode;
607 /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
609 if( plf->lfFaceName[0] )
611 if( dwUnicode )
613 WideCharToMultiByte( CP_ACP, 0, plf->lfFaceName, -1,
614 lf16.lfFaceName, LF_FACESIZE, NULL, NULL );
615 lf16.lfFaceName[LF_FACESIZE-1] = 0;
617 else
618 lstrcpynA( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
620 else lf16.lfFaceName[0] = '\0';
621 lf16.lfCharSet = plf->lfCharSet;
623 ret = enum_func( hDC, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
625 return ret;
628 /***********************************************************************
629 * EnumFontFamiliesExW (GDI32.82)
631 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
632 FONTENUMPROCEXW efproc,
633 LPARAM lParam, DWORD dwFlags )
635 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
638 /***********************************************************************
639 * EnumFontFamiliesExA (GDI32.81)
641 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
642 FONTENUMPROCEXA efproc,
643 LPARAM lParam, DWORD dwFlags)
645 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)plf,
646 (FONTENUMPROCEXW)efproc, lParam, 0);
649 /***********************************************************************
650 * EnumFontFamilies16 (GDI.330)
652 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
653 FONTENUMPROC16 efproc, LPARAM lpData )
655 LOGFONT16 lf;
657 lf.lfCharSet = DEFAULT_CHARSET;
658 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
659 else lf.lfFaceName[0] = '\0';
661 return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
664 /***********************************************************************
665 * EnumFontFamiliesA (GDI32.80)
667 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
668 FONTENUMPROCA efproc, LPARAM lpData )
670 LOGFONTA lf;
672 lf.lfCharSet = DEFAULT_CHARSET;
673 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
674 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
676 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)&lf,
677 (FONTENUMPROCEXW)efproc, lpData, 0 );
680 /***********************************************************************
681 * EnumFontFamiliesW (GDI32.83)
683 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
684 FONTENUMPROCW efproc, LPARAM lpData )
686 LOGFONTW lf;
688 lf.lfCharSet = DEFAULT_CHARSET;
689 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
690 else lf.lfFaceName[0] = 0;
692 return FONT_EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROCEXW)efproc,
693 lpData, ENUM_UNICODE );
696 /***********************************************************************
697 * EnumFonts16 (GDI.70)
699 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
700 LPARAM lpData )
702 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
705 /***********************************************************************
706 * EnumFontsA (GDI32.84)
708 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
709 LPARAM lpData )
711 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
714 /***********************************************************************
715 * EnumFontsW (GDI32.85)
717 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
718 LPARAM lpData )
720 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
724 /***********************************************************************
725 * GetTextCharacterExtra16 (GDI.89)
727 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
729 return (INT16)GetTextCharacterExtra( hdc );
733 /***********************************************************************
734 * GetTextCharacterExtra (GDI32.225)
736 INT WINAPI GetTextCharacterExtra( HDC hdc )
738 INT ret;
739 DC *dc = DC_GetDCPtr( hdc );
740 if (!dc) return 0;
741 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
742 / dc->vportExtX );
743 GDI_ReleaseObj( hdc );
744 return ret;
748 /***********************************************************************
749 * SetTextCharacterExtra16 (GDI.8)
751 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
753 return (INT16)SetTextCharacterExtra( hdc, extra );
757 /***********************************************************************
758 * SetTextCharacterExtra (GDI32.337)
760 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
762 INT prev;
763 DC * dc = DC_GetDCPtr( hdc );
764 if (!dc) return 0;
765 if (dc->funcs->pSetTextCharacterExtra)
766 prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
767 else
769 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
770 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
771 dc->charExtra = abs(extra);
773 GDI_ReleaseObj( hdc );
774 return prev;
778 /***********************************************************************
779 * SetTextJustification16 (GDI.10)
781 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
783 return SetTextJustification( hdc, extra, breaks );
787 /***********************************************************************
788 * SetTextJustification (GDI32.339)
790 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
792 BOOL ret = TRUE;
793 DC * dc = DC_GetDCPtr( hdc );
794 if (!dc) return FALSE;
795 if (dc->funcs->pSetTextJustification)
796 ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
797 else
799 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
800 if (!extra) breaks = 0;
801 dc->breakTotalExtra = extra;
802 dc->breakCount = breaks;
803 if (breaks)
805 dc->breakExtra = extra / breaks;
806 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
808 else
810 dc->breakExtra = 0;
811 dc->breakRem = 0;
814 GDI_ReleaseObj( hdc );
815 return ret;
819 /***********************************************************************
820 * GetTextFace16 (GDI.92)
822 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
824 return GetTextFaceA(hdc,count,name);
827 /***********************************************************************
828 * GetTextFaceA (GDI32.234)
830 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
832 FONTOBJ *font;
833 INT ret = 0;
835 DC * dc = DC_GetDCPtr( hdc );
836 if (!dc) return 0;
838 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
840 if (name)
842 lstrcpynA( name, font->logfont.lfFaceName, count );
843 ret = strlen(name);
845 else ret = strlen(font->logfont.lfFaceName) + 1;
846 GDI_ReleaseObj( dc->hFont );
848 GDI_ReleaseObj( hdc );
849 return ret;
852 /***********************************************************************
853 * GetTextFaceW (GDI32.235)
855 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
857 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
858 INT res = GetTextFaceA(hdc,count,nameA);
859 if (name) res = MultiByteToWideChar( CP_ACP, 0, nameA, -1, name, count );
860 HeapFree( GetProcessHeap(), 0, nameA );
861 return res;
865 /***********************************************************************
866 * GetTextExtent16 (GDI.91)
868 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
870 SIZE16 size;
871 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
872 return MAKELONG( size.cx, size.cy );
876 /***********************************************************************
877 * GetTextExtentPoint16 (GDI.471)
879 * FIXME: Should this have a bug for compatibility?
880 * Original Windows versions of GetTextExtentPoint{A,W} have documented
881 * bugs (-> MSDN KB q147647.txt).
883 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
884 LPSIZE16 size )
886 SIZE size32;
887 BOOL ret;
888 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count,
889 size);
890 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
891 CONV_SIZE32TO16( &size32, size );
892 return (BOOL16)ret;
896 /***********************************************************************
897 * GetTextExtentPoint32A (GDI32.230)
899 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
900 LPSIZE size )
902 BOOL ret = FALSE;
903 UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
904 DC * dc = DC_GetDCPtr( hdc );
906 if (!dc) return FALSE;
908 if (dc->funcs->pGetTextExtentPoint)
910 /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
911 * So we use MultiByteToWideChar.
913 UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
914 LPWSTR p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
915 if (p)
917 wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
918 ret = dc->funcs->pGetTextExtentPoint( dc, p, wlen, size );
919 HeapFree( GetProcessHeap(), 0, p );
922 GDI_ReleaseObj( hdc );
923 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
924 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
925 return ret;
929 /***********************************************************************
930 * GetTextExtentPoint32W [GDI32.231] Computes width/height for a string
932 * Computes width and height of the specified string.
934 * RETURNS
935 * Success: TRUE
936 * Failure: FALSE
938 BOOL WINAPI GetTextExtentPoint32W(
939 HDC hdc, /* [in] Handle of device context */
940 LPCWSTR str, /* [in] Address of text string */
941 INT count, /* [in] Number of characters in string */
942 LPSIZE size) /* [out] Address of structure for string size */
944 BOOL ret = FALSE;
945 DC * dc = DC_GetDCPtr( hdc );
946 if (dc)
948 if(dc->funcs->pGetTextExtentPoint)
949 ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
950 GDI_ReleaseObj( hdc );
952 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
953 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
954 return ret;
958 /***********************************************************************
959 * GetTextExtentPointA (GDI32.232)
961 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
962 LPSIZE size )
964 TRACE("not bug compatible.\n");
965 return GetTextExtentPoint32A( hdc, str, count, size );
968 /***********************************************************************
969 * GetTextExtentPointW (GDI32.233)
971 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
972 LPSIZE size )
974 TRACE("not bug compatible.\n");
975 return GetTextExtentPoint32W( hdc, str, count, size );
979 /***********************************************************************
980 * GetTextExtentExPointA (GDI32.228)
982 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
983 INT maxExt, LPINT lpnFit,
984 LPINT alpDx, LPSIZE size )
986 BOOL ret;
988 DWORD len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
989 LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
990 MultiByteToWideChar( CP_ACP, 0, str, count, p, len );
991 ret = GetTextExtentExPointW( hdc, p, len, maxExt, lpnFit, alpDx, size);
992 HeapFree( GetProcessHeap(), 0, p );
993 return ret;
997 /***********************************************************************
998 * GetTextExtentExPointW (GDI32.229)
1001 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1002 INT maxExt, LPINT lpnFit,
1003 LPINT alpDx, LPSIZE size )
1005 int index, nFit, extent;
1006 SIZE tSize;
1007 BOOL ret = FALSE;
1008 DC * dc = DC_GetDCPtr( hdc );
1009 if (!dc) return FALSE;
1011 if (!dc->funcs->pGetTextExtentPoint) goto done;
1013 size->cx = size->cy = nFit = extent = 0;
1014 for(index = 0; index < count; index++)
1016 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) goto done;
1017 if( extent+tSize.cx < maxExt )
1019 extent+=tSize.cx;
1020 nFit++;
1021 str++;
1022 if( alpDx ) alpDx[index] = extent;
1023 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1025 else break;
1027 size->cx = extent;
1028 *lpnFit = nFit;
1029 ret = TRUE;
1031 TRACE("(%08x %s %d) returning %d %ld x %ld\n",
1032 hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
1034 done:
1035 GDI_ReleaseObj( hdc );
1036 return ret;
1039 /***********************************************************************
1040 * GetTextMetrics16 (GDI.93)
1042 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1044 TEXTMETRICA tm32;
1046 if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
1047 FONT_TextMetric32Ato16( &tm32, metrics );
1048 return TRUE;
1052 /***********************************************************************
1053 * GetTextMetricsA (GDI32.236)
1055 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1057 BOOL ret = FALSE;
1058 DC * dc = DC_GetDCPtr( hdc );
1059 if (!dc) return FALSE;
1061 if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics ))
1063 /* device layer returns values in device units
1064 * therefore we have to convert them to logical */
1066 #define WDPTOLP(x) ((x<0)? \
1067 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1068 (abs((x)*dc->wndExtX/dc->vportExtX)))
1069 #define HDPTOLP(y) ((y<0)? \
1070 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1071 (abs((y)*dc->wndExtY/dc->vportExtY)))
1073 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1074 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1075 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1076 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1077 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1078 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1079 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1080 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1081 ret = TRUE;
1083 TRACE("text metrics:\n"
1084 " Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1085 " Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1086 " UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1087 " StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1088 " PitchAndFamily = %02x\n"
1089 " --------------------\n"
1090 " InternalLeading = %li\n"
1091 " Ascent = %li\n"
1092 " Descent = %li\n"
1093 " Height = %li\n",
1094 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1095 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1096 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1097 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1098 metrics->tmPitchAndFamily,
1099 metrics->tmInternalLeading,
1100 metrics->tmAscent,
1101 metrics->tmDescent,
1102 metrics->tmHeight );
1104 GDI_ReleaseObj( hdc );
1105 return ret;
1109 /***********************************************************************
1110 * GetTextMetricsW (GDI32.237)
1112 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1114 TEXTMETRICA tm;
1115 if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1116 FONT_TextMetric32Ato32W( &tm, metrics );
1117 return TRUE;
1121 /***********************************************************************
1122 * GetOutlineTextMetrics16 [GDI.308] Gets metrics for TrueType fonts.
1124 * NOTES
1125 * lpOTM should be LPOUTLINETEXTMETRIC
1127 * RETURNS
1128 * Success: Non-zero or size of required buffer
1129 * Failure: 0
1131 UINT16 WINAPI GetOutlineTextMetrics16(
1132 HDC16 hdc, /* [in] Handle of device context */
1133 UINT16 cbData, /* [in] Size of metric data array */
1134 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1136 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1137 return 0;
1141 /***********************************************************************
1142 * GetOutlineTextMetricsA [GDI.207] Gets metrics for TrueType fonts.
1145 * RETURNS
1146 * Success: Non-zero or size of required buffer
1147 * Failure: 0
1149 UINT WINAPI GetOutlineTextMetricsA(
1150 HDC hdc, /* [in] Handle of device context */
1151 UINT cbData, /* [in] Size of metric data array */
1152 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1156 UINT rtn = FALSE;
1157 LPTEXTMETRICA lptxtMetr;
1161 if (lpOTM == 0)
1164 lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1165 rtn = sizeof(OUTLINETEXTMETRICA);
1166 cbData = rtn;
1167 } else
1169 cbData = sizeof(*lpOTM);
1170 rtn = cbData;
1173 lpOTM->otmSize = cbData;
1175 lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1177 if (!GetTextMetricsA(hdc,lptxtMetr))
1179 return 0;
1180 } else
1182 memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1185 HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1187 lpOTM->otmFilter = 0;
1189 lpOTM->otmPanoseNumber.bFamilyType = 0;
1190 lpOTM->otmPanoseNumber.bSerifStyle = 0;
1191 lpOTM->otmPanoseNumber.bWeight = 0;
1192 lpOTM->otmPanoseNumber.bProportion = 0;
1193 lpOTM->otmPanoseNumber.bContrast = 0;
1194 lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1195 lpOTM->otmPanoseNumber.bArmStyle = 0;
1196 lpOTM->otmPanoseNumber.bLetterform = 0;
1197 lpOTM->otmPanoseNumber.bMidline = 0;
1198 lpOTM->otmPanoseNumber.bXHeight = 0;
1200 lpOTM->otmfsSelection = 0;
1201 lpOTM->otmfsType = 0;
1204 Further fill of the structure not implemented,
1205 Needs real values for the structure members
1208 return rtn;
1211 /***********************************************************************
1212 * GetOutlineTextMetricsW [GDI32.208]
1214 UINT WINAPI GetOutlineTextMetricsW(
1215 HDC hdc, /* [in] Handle of device context */
1216 UINT cbData, /* [in] Size of metric data array */
1217 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1219 FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1220 return 0;
1223 /***********************************************************************
1224 * GetCharWidth16 (GDI.350)
1226 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1227 LPINT16 buffer )
1229 BOOL retVal = FALSE;
1231 if( firstChar != lastChar )
1233 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1234 sizeof(INT)*(1 + (lastChar - firstChar)));
1235 if( buf32 )
1237 LPINT obuf32 = buf32;
1238 int i;
1240 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1241 if (retVal)
1243 for (i = firstChar; i <= lastChar; i++)
1244 *buffer++ = *buf32++;
1246 HeapFree(GetProcessHeap(), 0, obuf32);
1249 else /* happens quite often to warrant a special treatment */
1251 INT chWidth;
1252 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1253 *buffer = chWidth;
1255 return retVal;
1259 /***********************************************************************
1260 * GetCharWidth32A (GDI32.155)
1262 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1263 LPINT buffer )
1265 UINT i, extra;
1266 BOOL ret = FALSE;
1267 DC * dc = DC_GetDCPtr( hdc );
1268 if (!dc) return FALSE;
1270 if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1272 /* convert device units to logical */
1274 extra = dc->vportExtX >> 1;
1275 for( i = firstChar; i <= lastChar; i++, buffer++ )
1276 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1277 ret = TRUE;
1279 GDI_ReleaseObj( hdc );
1280 return ret;
1284 /***********************************************************************
1285 * GetCharWidth32W (GDI32.158)
1287 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1288 LPINT buffer )
1290 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1294 /* FIXME: all following APIs ******************************************/
1297 /***********************************************************************
1298 * SetMapperFlags16 (GDI.349)
1300 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1302 return SetMapperFlags( hDC, dwFlag );
1306 /***********************************************************************
1307 * SetMapperFlags (GDI32.322)
1309 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1311 DC *dc = DC_GetDCPtr( hDC );
1312 DWORD ret = 0;
1313 if(!dc) return 0;
1314 if(dc->funcs->pSetMapperFlags)
1315 ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1316 else
1317 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1318 GDI_ReleaseObj( hDC );
1319 return ret;
1322 /***********************************************************************
1323 * GetAspectRatioFilterEx16 (GDI.486)
1325 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1327 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1328 return FALSE;
1331 /***********************************************************************
1332 * GetAspectRatioFilterEx (GDI32.142)
1334 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1336 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1337 return FALSE;
1340 /***********************************************************************
1341 * GetCharABCWidths16 (GDI.307)
1343 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1344 LPABC16 abc )
1346 ABC abc32;
1347 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1348 abc->abcA = abc32.abcA;
1349 abc->abcB = abc32.abcB;
1350 abc->abcC = abc32.abcC;
1351 return TRUE;
1355 /***********************************************************************
1356 * GetCharABCWidthsA (GDI32.149)
1358 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1359 LPABC abc )
1361 return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1365 /******************************************************************************
1366 * GetCharABCWidthsW [GDI32.152] Retrieves widths of characters in range
1368 * PARAMS
1369 * hdc [I] Handle of device context
1370 * firstChar [I] First character in range to query
1371 * lastChar [I] Last character in range to query
1372 * abc [O] Address of character-width structure
1374 * NOTES
1375 * Only works with TrueType fonts
1377 * RETURNS
1378 * Success: TRUE
1379 * Failure: FALSE
1381 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1382 LPABC abc )
1384 /* No TrueType fonts in Wine so far */
1385 FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1386 return FALSE;
1390 /***********************************************************************
1391 * GetGlyphOutline16 (GDI.309)
1393 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1394 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1395 LPVOID lpBuffer, const MAT2 *lpmat2 )
1397 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1398 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1399 return (DWORD)-1; /* failure */
1403 /***********************************************************************
1404 * GetGlyphOutlineA (GDI32.186)
1406 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1407 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1408 LPVOID lpBuffer, const MAT2 *lpmat2 )
1410 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1411 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1412 return (DWORD)-1; /* failure */
1415 /***********************************************************************
1416 * GetGlyphOutlineW (GDI32.187)
1418 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1419 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1420 LPVOID lpBuffer, const MAT2 *lpmat2 )
1422 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1423 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1424 return (DWORD)-1; /* failure */
1427 /***********************************************************************
1428 * CreateScalableFontResource16 (GDI.310)
1430 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1431 LPCSTR lpszResourceFile,
1432 LPCSTR fontFile, LPCSTR path )
1434 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1435 fontFile, path );
1438 /***********************************************************************
1439 * CreateScalableFontResourceA (GDI32.62)
1441 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1442 LPCSTR lpszResourceFile,
1443 LPCSTR lpszFontFile,
1444 LPCSTR lpszCurrentPath )
1446 /* fHidden=1 - only visible for the calling app, read-only, not
1447 * enumbered with EnumFonts/EnumFontFamilies
1448 * lpszCurrentPath can be NULL
1450 FIXME("(%ld,%s,%s,%s): stub\n",
1451 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1452 return FALSE; /* create failed */
1455 /***********************************************************************
1456 * CreateScalableFontResourceW (GDI32.63)
1458 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1459 LPCWSTR lpszResourceFile,
1460 LPCWSTR lpszFontFile,
1461 LPCWSTR lpszCurrentPath )
1463 FIXME("(%ld,%p,%p,%p): stub\n",
1464 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1465 return FALSE; /* create failed */
1469 /*************************************************************************
1470 * GetRasterizerCaps16 (GDI.313)
1472 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1474 return GetRasterizerCaps( lprs, cbNumBytes );
1478 /*************************************************************************
1479 * GetRasterizerCaps (GDI32.216)
1481 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1483 lprs->nSize = sizeof(RASTERIZER_STATUS);
1484 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1485 lprs->nLanguageID = 0;
1486 return TRUE;
1490 /*************************************************************************
1491 * GetKerningPairs16 (GDI.332)
1493 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1494 LPKERNINGPAIR16 lpKerningPairs )
1496 /* At this time kerning is ignored (set to 0) */
1497 int i;
1498 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1499 for (i = 0; i < cPairs; i++)
1500 lpKerningPairs[i].iKernAmount = 0;
1501 return 0;
1506 /*************************************************************************
1507 * GetKerningPairsA (GDI32.192)
1509 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1510 LPKERNINGPAIR lpKerningPairs )
1512 int i;
1513 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1514 for (i = 0; i < cPairs; i++)
1515 lpKerningPairs[i].iKernAmount = 0;
1516 return 0;
1520 /*************************************************************************
1521 * GetKerningPairsW (GDI32.193)
1523 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1524 LPKERNINGPAIR lpKerningPairs )
1526 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1529 /*************************************************************************
1530 * TranslateCharsetInfo [GDI32.382]
1532 * Fills a CHARSETINFO structure for a character set, code page, or
1533 * font. This allows making the correspondance between different labelings
1534 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1535 * of the same encoding.
1537 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1538 * only one codepage should be set in *lpSrc.
1540 * RETURNS
1541 * TRUE on success, FALSE on failure.
1544 BOOL WINAPI TranslateCharsetInfo(
1545 LPDWORD lpSrc, /* [in]
1546 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1547 if flags == TCI_SRCCHARSET: a character set value
1548 if flags == TCI_SRCCODEPAGE: a code page value
1550 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1551 DWORD flags /* [in] determines interpretation of lpSrc */
1553 int index = 0;
1554 switch (flags) {
1555 case TCI_SRCFONTSIG:
1556 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1557 break;
1558 case TCI_SRCCODEPAGE:
1559 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1560 break;
1561 case TCI_SRCCHARSET:
1562 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1563 break;
1564 default:
1565 return FALSE;
1567 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1568 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1569 return TRUE;
1572 /*************************************************************************
1573 * GetFontLanguageInfo (GDI32.182)
1575 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1576 /* return value 0 is correct for most cases anyway */
1577 FIXME("(%x):stub!\n", hdc);
1578 return 0;
1581 /*************************************************************************
1582 * GetFontLanguageInfo (GDI.616)
1584 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1585 /* return value 0 is correct for most cases anyway */
1586 FIXME("(%x):stub!\n",hdc);
1587 return 0;
1590 /*************************************************************************
1591 * GetFontData [GDI32.181] Retrieve data for TrueType font
1593 * RETURNS
1595 * success: Number of bytes returned
1596 * failure: GDI_ERROR
1598 * NOTES
1600 * Calls SetLastError()
1602 * BUGS
1604 * Unimplemented
1606 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1607 LPVOID buffer, DWORD length)
1609 FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1610 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1611 return GDI_ERROR;
1614 /*************************************************************************
1615 * GetFontData16 [GDI.311]
1618 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1619 LPVOID lpvBuffer, DWORD cbData)
1621 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1624 /*************************************************************************
1625 * GetCharacterPlacementA [GDI32.160]
1627 * NOTES:
1628 * the web browser control of ie4 calls this with dwFlags=0
1630 DWORD WINAPI
1631 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1632 INT nMaxExtent, GCP_RESULTSA *lpResults,
1633 DWORD dwFlags)
1635 DWORD ret=0;
1636 SIZE size;
1638 TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1639 debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1641 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1642 "lpOutString=%p lpGlyphs=%p\n",
1643 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1644 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1646 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
1647 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
1648 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1649 if(lpResults->lpClass) FIXME("classes not implemented\n");
1650 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
1652 /* copy will do if the GCP_REORDER flag is not set */
1653 if(lpResults->lpOutString)
1655 lstrcpynA(lpResults->lpOutString, lpString, uCount);
1658 if (lpResults->lpDx)
1660 int i, c;
1661 for (i=0; i<uCount;i++)
1663 if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1664 lpResults->lpDx[i]= c;
1668 if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1669 ret = MAKELONG(size.cx, size.cy);
1671 return ret;
1674 /*************************************************************************
1675 * GetCharacterPlacementW [GDI32.161]
1677 DWORD WINAPI
1678 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1679 INT nMaxExtent, GCP_RESULTSW *lpResults,
1680 DWORD dwFlags)
1682 /* return value 0 is correct for most cases anyway */
1683 FIXME(":stub!\n");
1684 return 0;
1687 /*************************************************************************
1688 * GetCharABCWidthsFloatA [GDI32.150]
1690 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1691 LPABCFLOAT lpABCF)
1693 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1694 return 0;
1697 /*************************************************************************
1698 * GetCharABCWidthsFloatW [GDI32.151]
1700 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1701 UINT iLastChar, LPABCFLOAT lpABCF)
1703 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1704 return 0;
1707 /*************************************************************************
1708 * GetCharWidthFloatA [GDI32.156]
1710 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1711 UINT iLastChar, PFLOAT pxBuffer)
1713 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1714 return 0;
1717 /*************************************************************************
1718 * GetCharWidthFloatW [GDI32.157]
1720 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1721 UINT iLastChar, PFLOAT pxBuffer)
1723 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1724 return 0;
1728 /***********************************************************************
1730 * Font Resource API *
1732 ***********************************************************************/
1733 /***********************************************************************
1734 * AddFontResource16 (GDI.119)
1736 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1738 * FIXME: Load header and find the best-matching font in the fontList;
1739 * fixup dfPoints if all metrics are identical, otherwise create
1740 * new fontAlias. When soft font support is ready this will
1741 * simply create a new fontResource ('filename' will go into
1742 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
1743 * flag set.
1745 INT16 WINAPI AddFontResource16( LPCSTR filename )
1747 return AddFontResourceA( filename );
1751 /***********************************************************************
1752 * AddFontResourceA (GDI32.2)
1754 INT WINAPI AddFontResourceA( LPCSTR str )
1756 FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1757 "this font manually.\n", debugres_a(str));
1758 return 1;
1762 /***********************************************************************
1763 * AddFontResourceW (GDI32.4)
1765 INT WINAPI AddFontResourceW( LPCWSTR str )
1767 FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1768 "this font manually.\n", debugres_w(str));
1769 return 1;
1772 /***********************************************************************
1773 * RemoveFontResource16 (GDI.136)
1775 BOOL16 WINAPI RemoveFontResource16( SEGPTR str )
1777 FIXME("(%s): stub\n", debugres_a(PTR_SEG_TO_LIN(str)));
1778 return TRUE;
1782 /***********************************************************************
1783 * RemoveFontResourceA (GDI32.284)
1785 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1787 /* This is how it should look like */
1789 fontResource** ppfr;
1790 BOOL32 retVal = FALSE;
1792 EnterCriticalSection( &crtsc_fonts_X11 );
1793 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1794 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1796 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1797 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1799 if( (*ppfr)->fo_count )
1800 (*ppfr)->fr_flags |= FR_REMOVED;
1801 else
1802 XFONT_RemoveFontResource( ppfr );
1804 retVal = TRUE;
1806 LeaveCriticalSection( &crtsc_fonts_X11 );
1807 return retVal;
1809 FIXME("(%s): stub\n", debugres_a(str));
1810 return TRUE;
1814 /***********************************************************************
1815 * RemoveFontResourceW (GDI32.286)
1817 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1819 FIXME("(%s): stub\n", debugres_w(str) );
1820 return TRUE;