Ownerdrawn combo boxes should use ODS_COMBOBOXEDIT in the itemState.
[wine.git] / objects / font.c
blobf1cfedd464eaf89f60b5bff2d1ee40b20d432dfe
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 if (font) {
357 FONT_LogFont32ATo16( font, &font16 );
358 return CreateFontIndirect16( &font16 );
359 } else
360 return CreateFontIndirect16( NULL );
364 /***********************************************************************
365 * CreateFontIndirectW (GDI32.45)
367 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *font )
369 LOGFONT16 font16;
371 if (font) {
372 FONT_LogFont32WTo16( font, &font16 );
373 return CreateFontIndirect16( &font16 );
374 } else
375 return CreateFontIndirect16( NULL );
378 /***********************************************************************
379 * CreateFont16 (GDI.56)
381 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
382 INT16 weight, BYTE italic, BYTE underline,
383 BYTE strikeout, BYTE charset, BYTE outpres,
384 BYTE clippres, BYTE quality, BYTE pitch,
385 LPCSTR name )
387 LOGFONT16 logfont;
389 TRACE("('%s',%d,%d)\n", (name ? name : "(null)") , height, width);
391 logfont.lfHeight = height;
392 logfont.lfWidth = width;
393 logfont.lfEscapement = esc;
394 logfont.lfOrientation = orient;
395 logfont.lfWeight = weight;
396 logfont.lfItalic = italic;
397 logfont.lfUnderline = underline;
398 logfont.lfStrikeOut = strikeout;
399 logfont.lfCharSet = charset;
400 logfont.lfOutPrecision = outpres;
401 logfont.lfClipPrecision = clippres;
402 logfont.lfQuality = quality;
403 logfont.lfPitchAndFamily = pitch;
405 if (name)
406 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
407 else
408 logfont.lfFaceName[0] = '\0';
410 return CreateFontIndirect16( &logfont );
413 /*************************************************************************
414 * CreateFontA (GDI32.43)
416 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
417 INT orient, INT weight, DWORD italic,
418 DWORD underline, DWORD strikeout, DWORD charset,
419 DWORD outpres, DWORD clippres, DWORD quality,
420 DWORD pitch, LPCSTR name )
422 return (HFONT)CreateFont16( height, width, esc, orient, weight, italic,
423 underline, strikeout, charset, outpres,
424 clippres, quality, pitch, name );
427 /*************************************************************************
428 * CreateFontW (GDI32.46)
430 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
431 INT orient, INT weight, DWORD italic,
432 DWORD underline, DWORD strikeout, DWORD charset,
433 DWORD outpres, DWORD clippres, DWORD quality,
434 DWORD pitch, LPCWSTR name )
436 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
437 HFONT ret = (HFONT)CreateFont16( height, width, esc, orient, weight,
438 italic, underline, strikeout, charset,
439 outpres, clippres, quality, pitch,
440 namea );
441 if (namea) HeapFree( GetProcessHeap(), 0, namea );
442 return ret;
446 /***********************************************************************
447 * FONT_GetObject16
449 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
451 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
452 memcpy( buffer, &font->logfont, count );
453 return count;
456 /***********************************************************************
457 * FONT_GetObjectA
459 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
461 LOGFONTA fnt32;
463 FONT_LogFont16To32A( &font->logfont, &fnt32 );
465 if (count > sizeof(fnt32)) count = sizeof(fnt32);
466 memcpy( buffer, &fnt32, count );
467 return count;
469 /***********************************************************************
470 * FONT_GetObjectW
472 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
474 LOGFONTW fnt32;
476 FONT_LogFont16To32W( &font->logfont, &fnt32 );
478 if (count > sizeof(fnt32)) count = sizeof(fnt32);
479 memcpy( buffer, &fnt32, count );
480 return count;
484 /***********************************************************************
485 * FONT_EnumInstance16
487 * Called by the device driver layer to pass font info
488 * down to the application.
490 static INT FONT_EnumInstance16( LPENUMLOGFONTEX16 plf,
491 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
493 #define pfe ((fontEnum16*)lp)
494 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
495 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
497 memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
498 memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
500 return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
502 #undef pfe
503 return 1;
506 /***********************************************************************
507 * FONT_EnumInstance
509 static INT FONT_EnumInstance( LPENUMLOGFONTEX16 plf,
510 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
512 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
514 #define pfe ((fontEnum32*)lp)
515 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
516 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
518 /* convert font metrics */
520 if( pfe->dwFlags & ENUM_UNICODE )
522 FONT_EnumLogFontEx16To32W( plf, pfe->lpLogFont );
523 FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICW)(pfe->lpTextMetric) );
525 return pfe->lpEnumFunc( pfe->lpLogFont, pfe->lpTextMetric, fType, pfe->lpData );
527 else
529 ENUMLOGFONTEXA logfont;
531 FONT_EnumLogFontEx16To32A( plf, &logfont);
532 FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICA)pfe->lpTextMetric );
534 return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
535 pfe->lpTextMetric, fType, pfe->lpData );
538 #undef pfe
539 return 1;
542 /***********************************************************************
543 * EnumFontFamiliesEx16 (GDI.613)
545 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
546 FONTENUMPROCEX16 efproc, LPARAM lParam,
547 DWORD dwFlags)
549 BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
550 INT16 retVal = 0;
551 DC* dc = DC_GetDCPtr( hDC );
553 if (!dc) return 0;
554 enum_func = dc->funcs->pEnumDeviceFonts;
555 GDI_ReleaseObj( hDC );
557 if (enum_func)
559 LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
560 if( lptm16 )
562 LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
563 if( lplf16 )
565 fontEnum16 fe16;
567 fe16.lpLogFontParam = plf;
568 fe16.lpEnumFunc = efproc;
569 fe16.lpData = lParam;
571 fe16.lpTextMetric = lptm16;
572 fe16.lpLogFont = lplf16;
573 fe16.segTextMetric = SEGPTR_GET(lptm16);
574 fe16.segLogFont = SEGPTR_GET(lplf16);
576 retVal = enum_func( hDC, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
577 SEGPTR_FREE(lplf16);
579 SEGPTR_FREE(lptm16);
582 return retVal;
585 /***********************************************************************
586 * FONT_EnumFontFamiliesEx
588 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc,
589 LPARAM lParam, DWORD dwUnicode)
591 BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
592 INT ret = 0;
593 DC *dc = DC_GetDCPtr( hDC );
595 if (!dc) return 0;
596 enum_func = dc->funcs->pEnumDeviceFonts;
597 GDI_ReleaseObj( hDC );
599 if (enum_func)
601 LOGFONT16 lf16;
602 NEWTEXTMETRICEXW tm32w;
603 ENUMLOGFONTEXW lf32w;
604 fontEnum32 fe32;
606 fe32.lpLogFontParam = plf;
607 fe32.lpEnumFunc = efproc;
608 fe32.lpData = lParam;
610 fe32.lpTextMetric = &tm32w;
611 fe32.lpLogFont = &lf32w;
612 fe32.dwFlags = dwUnicode;
614 /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
616 if( plf->lfFaceName[0] )
618 if( dwUnicode )
620 WideCharToMultiByte( CP_ACP, 0, plf->lfFaceName, -1,
621 lf16.lfFaceName, LF_FACESIZE, NULL, NULL );
622 lf16.lfFaceName[LF_FACESIZE-1] = 0;
624 else
625 lstrcpynA( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
627 else lf16.lfFaceName[0] = '\0';
628 lf16.lfCharSet = plf->lfCharSet;
630 ret = enum_func( hDC, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
632 return ret;
635 /***********************************************************************
636 * EnumFontFamiliesExW (GDI32.82)
638 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
639 FONTENUMPROCEXW efproc,
640 LPARAM lParam, DWORD dwFlags )
642 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
645 /***********************************************************************
646 * EnumFontFamiliesExA (GDI32.81)
648 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
649 FONTENUMPROCEXA efproc,
650 LPARAM lParam, DWORD dwFlags)
652 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)plf,
653 (FONTENUMPROCEXW)efproc, lParam, 0);
656 /***********************************************************************
657 * EnumFontFamilies16 (GDI.330)
659 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
660 FONTENUMPROC16 efproc, LPARAM lpData )
662 LOGFONT16 lf;
664 lf.lfCharSet = DEFAULT_CHARSET;
665 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
666 else lf.lfFaceName[0] = '\0';
668 return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
671 /***********************************************************************
672 * EnumFontFamiliesA (GDI32.80)
674 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
675 FONTENUMPROCA efproc, LPARAM lpData )
677 LOGFONTA lf;
679 lf.lfCharSet = DEFAULT_CHARSET;
680 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
681 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
683 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)&lf,
684 (FONTENUMPROCEXW)efproc, lpData, 0 );
687 /***********************************************************************
688 * EnumFontFamiliesW (GDI32.83)
690 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
691 FONTENUMPROCW efproc, LPARAM lpData )
693 LOGFONTW lf;
695 lf.lfCharSet = DEFAULT_CHARSET;
696 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
697 else lf.lfFaceName[0] = 0;
699 return FONT_EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROCEXW)efproc,
700 lpData, ENUM_UNICODE );
703 /***********************************************************************
704 * EnumFonts16 (GDI.70)
706 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
707 LPARAM lpData )
709 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
712 /***********************************************************************
713 * EnumFontsA (GDI32.84)
715 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
716 LPARAM lpData )
718 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
721 /***********************************************************************
722 * EnumFontsW (GDI32.85)
724 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
725 LPARAM lpData )
727 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
731 /***********************************************************************
732 * GetTextCharacterExtra16 (GDI.89)
734 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
736 return (INT16)GetTextCharacterExtra( hdc );
740 /***********************************************************************
741 * GetTextCharacterExtra (GDI32.225)
743 INT WINAPI GetTextCharacterExtra( HDC hdc )
745 INT ret;
746 DC *dc = DC_GetDCPtr( hdc );
747 if (!dc) return 0;
748 ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
749 / dc->vportExtX );
750 GDI_ReleaseObj( hdc );
751 return ret;
755 /***********************************************************************
756 * SetTextCharacterExtra16 (GDI.8)
758 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
760 return (INT16)SetTextCharacterExtra( hdc, extra );
764 /***********************************************************************
765 * SetTextCharacterExtra (GDI32.337)
767 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
769 INT prev;
770 DC * dc = DC_GetDCPtr( hdc );
771 if (!dc) return 0;
772 if (dc->funcs->pSetTextCharacterExtra)
773 prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
774 else
776 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
777 prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
778 dc->charExtra = abs(extra);
780 GDI_ReleaseObj( hdc );
781 return prev;
785 /***********************************************************************
786 * SetTextJustification16 (GDI.10)
788 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
790 return SetTextJustification( hdc, extra, breaks );
794 /***********************************************************************
795 * SetTextJustification (GDI32.339)
797 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
799 BOOL ret = TRUE;
800 DC * dc = DC_GetDCPtr( hdc );
801 if (!dc) return FALSE;
802 if (dc->funcs->pSetTextJustification)
803 ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
804 else
806 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
807 if (!extra) breaks = 0;
808 dc->breakTotalExtra = extra;
809 dc->breakCount = breaks;
810 if (breaks)
812 dc->breakExtra = extra / breaks;
813 dc->breakRem = extra - (dc->breakCount * dc->breakExtra);
815 else
817 dc->breakExtra = 0;
818 dc->breakRem = 0;
821 GDI_ReleaseObj( hdc );
822 return ret;
826 /***********************************************************************
827 * GetTextFace16 (GDI.92)
829 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
831 return GetTextFaceA(hdc,count,name);
834 /***********************************************************************
835 * GetTextFaceA (GDI32.234)
837 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
839 FONTOBJ *font;
840 INT ret = 0;
842 DC * dc = DC_GetDCPtr( hdc );
843 if (!dc) return 0;
845 if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
847 if (name)
849 lstrcpynA( name, font->logfont.lfFaceName, count );
850 ret = strlen(name);
852 else ret = strlen(font->logfont.lfFaceName) + 1;
853 GDI_ReleaseObj( dc->hFont );
855 GDI_ReleaseObj( hdc );
856 return ret;
859 /***********************************************************************
860 * GetTextFaceW (GDI32.235)
862 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
864 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
865 INT res = GetTextFaceA(hdc,count,nameA);
866 if (name) res = MultiByteToWideChar( CP_ACP, 0, nameA, -1, name, count );
867 HeapFree( GetProcessHeap(), 0, nameA );
868 return res;
872 /***********************************************************************
873 * GetTextExtent16 (GDI.91)
875 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
877 SIZE16 size;
878 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
879 return MAKELONG( size.cx, size.cy );
883 /***********************************************************************
884 * GetTextExtentPoint16 (GDI.471)
886 * FIXME: Should this have a bug for compatibility?
887 * Original Windows versions of GetTextExtentPoint{A,W} have documented
888 * bugs (-> MSDN KB q147647.txt).
890 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
891 LPSIZE16 size )
893 SIZE size32;
894 BOOL ret;
895 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
896 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
897 size->cx = size32.cx;
898 size->cy = size32.cy;
899 return (BOOL16)ret;
903 /***********************************************************************
904 * GetTextExtentPoint32A (GDI32.230)
906 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
907 LPSIZE size )
909 BOOL ret = FALSE;
910 UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
911 DC * dc = DC_GetDCPtr( hdc );
913 if (!dc) return FALSE;
915 if (dc->funcs->pGetTextExtentPoint)
917 /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
918 * So we use MultiByteToWideChar.
920 UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
921 LPWSTR p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
922 if (p)
924 wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
925 ret = dc->funcs->pGetTextExtentPoint( dc, p, wlen, size );
926 HeapFree( GetProcessHeap(), 0, p );
929 GDI_ReleaseObj( hdc );
930 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
931 hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
932 return ret;
936 /***********************************************************************
937 * GetTextExtentPoint32W [GDI32.231] Computes width/height for a string
939 * Computes width and height of the specified string.
941 * RETURNS
942 * Success: TRUE
943 * Failure: FALSE
945 BOOL WINAPI GetTextExtentPoint32W(
946 HDC hdc, /* [in] Handle of device context */
947 LPCWSTR str, /* [in] Address of text string */
948 INT count, /* [in] Number of characters in string */
949 LPSIZE size) /* [out] Address of structure for string size */
951 BOOL ret = FALSE;
952 DC * dc = DC_GetDCPtr( hdc );
953 if (dc)
955 if(dc->funcs->pGetTextExtentPoint)
956 ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
957 GDI_ReleaseObj( hdc );
959 TRACE("(%08x %s %d %p): returning %ld x %ld\n",
960 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
961 return ret;
965 /***********************************************************************
966 * GetTextExtentPointA (GDI32.232)
968 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
969 LPSIZE size )
971 TRACE("not bug compatible.\n");
972 return GetTextExtentPoint32A( hdc, str, count, size );
975 /***********************************************************************
976 * GetTextExtentPointW (GDI32.233)
978 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
979 LPSIZE size )
981 TRACE("not bug compatible.\n");
982 return GetTextExtentPoint32W( hdc, str, count, size );
986 /***********************************************************************
987 * GetTextExtentExPointA (GDI32.228)
989 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
990 INT maxExt, LPINT lpnFit,
991 LPINT alpDx, LPSIZE size )
993 BOOL ret;
995 DWORD len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
996 LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
997 MultiByteToWideChar( CP_ACP, 0, str, count, p, len );
998 ret = GetTextExtentExPointW( hdc, p, len, maxExt, lpnFit, alpDx, size);
999 HeapFree( GetProcessHeap(), 0, p );
1000 return ret;
1004 /***********************************************************************
1005 * GetTextExtentExPointW (GDI32.229)
1008 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1009 INT maxExt, LPINT lpnFit,
1010 LPINT alpDx, LPSIZE size )
1012 int index, nFit, extent;
1013 SIZE tSize;
1014 BOOL ret = FALSE;
1015 DC * dc = DC_GetDCPtr( hdc );
1016 if (!dc) return FALSE;
1018 if (!dc->funcs->pGetTextExtentPoint) goto done;
1020 size->cx = size->cy = nFit = extent = 0;
1021 for(index = 0; index < count; index++)
1023 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) goto done;
1024 if( extent+tSize.cx < maxExt )
1026 extent+=tSize.cx;
1027 nFit++;
1028 str++;
1029 if( alpDx ) alpDx[index] = extent;
1030 if( tSize.cy > size->cy ) size->cy = tSize.cy;
1032 else break;
1034 size->cx = extent;
1035 *lpnFit = nFit;
1036 ret = TRUE;
1038 TRACE("(%08x %s %d) returning %d %ld x %ld\n",
1039 hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
1041 done:
1042 GDI_ReleaseObj( hdc );
1043 return ret;
1046 /***********************************************************************
1047 * GetTextMetrics16 (GDI.93)
1049 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1051 TEXTMETRICA tm32;
1053 if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
1054 FONT_TextMetric32Ato16( &tm32, metrics );
1055 return TRUE;
1059 /***********************************************************************
1060 * GetTextMetricsA (GDI32.236)
1062 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1064 BOOL ret = FALSE;
1065 DC * dc = DC_GetDCPtr( hdc );
1066 if (!dc) return FALSE;
1068 if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics ))
1070 /* device layer returns values in device units
1071 * therefore we have to convert them to logical */
1073 #define WDPTOLP(x) ((x<0)? \
1074 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1075 (abs((x)*dc->wndExtX/dc->vportExtX)))
1076 #define HDPTOLP(y) ((y<0)? \
1077 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1078 (abs((y)*dc->wndExtY/dc->vportExtY)))
1080 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1081 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1082 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1083 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1084 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1085 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1086 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1087 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1088 ret = TRUE;
1090 TRACE("text metrics:\n"
1091 " Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1092 " Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1093 " UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1094 " StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1095 " PitchAndFamily = %02x\n"
1096 " --------------------\n"
1097 " InternalLeading = %li\n"
1098 " Ascent = %li\n"
1099 " Descent = %li\n"
1100 " Height = %li\n",
1101 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1102 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1103 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1104 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1105 metrics->tmPitchAndFamily,
1106 metrics->tmInternalLeading,
1107 metrics->tmAscent,
1108 metrics->tmDescent,
1109 metrics->tmHeight );
1111 GDI_ReleaseObj( hdc );
1112 return ret;
1116 /***********************************************************************
1117 * GetTextMetricsW (GDI32.237)
1119 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1121 TEXTMETRICA tm;
1122 if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1123 FONT_TextMetric32Ato32W( &tm, metrics );
1124 return TRUE;
1128 /***********************************************************************
1129 * GetOutlineTextMetrics16 [GDI.308] Gets metrics for TrueType fonts.
1131 * NOTES
1132 * lpOTM should be LPOUTLINETEXTMETRIC
1134 * RETURNS
1135 * Success: Non-zero or size of required buffer
1136 * Failure: 0
1138 UINT16 WINAPI GetOutlineTextMetrics16(
1139 HDC16 hdc, /* [in] Handle of device context */
1140 UINT16 cbData, /* [in] Size of metric data array */
1141 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1143 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1144 return 0;
1148 /***********************************************************************
1149 * GetOutlineTextMetricsA [GDI.207] Gets metrics for TrueType fonts.
1152 * RETURNS
1153 * Success: Non-zero or size of required buffer
1154 * Failure: 0
1156 UINT WINAPI GetOutlineTextMetricsA(
1157 HDC hdc, /* [in] Handle of device context */
1158 UINT cbData, /* [in] Size of metric data array */
1159 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1163 UINT rtn = FALSE;
1164 LPTEXTMETRICA lptxtMetr;
1168 if (lpOTM == 0)
1171 lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1172 rtn = sizeof(OUTLINETEXTMETRICA);
1173 cbData = rtn;
1174 } else
1176 cbData = sizeof(*lpOTM);
1177 rtn = cbData;
1180 lpOTM->otmSize = cbData;
1182 lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1184 if (!GetTextMetricsA(hdc,lptxtMetr))
1186 return 0;
1187 } else
1189 memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1192 HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1194 lpOTM->otmFilter = 0;
1196 lpOTM->otmPanoseNumber.bFamilyType = 0;
1197 lpOTM->otmPanoseNumber.bSerifStyle = 0;
1198 lpOTM->otmPanoseNumber.bWeight = 0;
1199 lpOTM->otmPanoseNumber.bProportion = 0;
1200 lpOTM->otmPanoseNumber.bContrast = 0;
1201 lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1202 lpOTM->otmPanoseNumber.bArmStyle = 0;
1203 lpOTM->otmPanoseNumber.bLetterform = 0;
1204 lpOTM->otmPanoseNumber.bMidline = 0;
1205 lpOTM->otmPanoseNumber.bXHeight = 0;
1207 lpOTM->otmfsSelection = 0;
1208 lpOTM->otmfsType = 0;
1211 Further fill of the structure not implemented,
1212 Needs real values for the structure members
1215 return rtn;
1218 /***********************************************************************
1219 * GetOutlineTextMetricsW [GDI32.208]
1221 UINT WINAPI GetOutlineTextMetricsW(
1222 HDC hdc, /* [in] Handle of device context */
1223 UINT cbData, /* [in] Size of metric data array */
1224 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1226 FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1227 return 0;
1230 /***********************************************************************
1231 * GetCharWidth16 (GDI.350)
1233 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1234 LPINT16 buffer )
1236 BOOL retVal = FALSE;
1238 if( firstChar != lastChar )
1240 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1241 sizeof(INT)*(1 + (lastChar - firstChar)));
1242 if( buf32 )
1244 LPINT obuf32 = buf32;
1245 int i;
1247 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1248 if (retVal)
1250 for (i = firstChar; i <= lastChar; i++)
1251 *buffer++ = *buf32++;
1253 HeapFree(GetProcessHeap(), 0, obuf32);
1256 else /* happens quite often to warrant a special treatment */
1258 INT chWidth;
1259 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1260 *buffer = chWidth;
1262 return retVal;
1266 /***********************************************************************
1267 * GetCharWidth32A (GDI32.155)
1269 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1270 LPINT buffer )
1272 UINT i, extra;
1273 BOOL ret = FALSE;
1274 DC * dc = DC_GetDCPtr( hdc );
1275 if (!dc) return FALSE;
1277 if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1279 /* convert device units to logical */
1281 extra = dc->vportExtX >> 1;
1282 for( i = firstChar; i <= lastChar; i++, buffer++ )
1283 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1284 ret = TRUE;
1286 GDI_ReleaseObj( hdc );
1287 return ret;
1291 /***********************************************************************
1292 * GetCharWidth32W (GDI32.158)
1294 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1295 LPINT buffer )
1297 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1301 /* FIXME: all following APIs ******************************************/
1304 /***********************************************************************
1305 * SetMapperFlags16 (GDI.349)
1307 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1309 return SetMapperFlags( hDC, dwFlag );
1313 /***********************************************************************
1314 * SetMapperFlags (GDI32.322)
1316 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1318 DC *dc = DC_GetDCPtr( hDC );
1319 DWORD ret = 0;
1320 if(!dc) return 0;
1321 if(dc->funcs->pSetMapperFlags)
1322 ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1323 else
1324 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1325 GDI_ReleaseObj( hDC );
1326 return ret;
1329 /***********************************************************************
1330 * GetAspectRatioFilterEx16 (GDI.486)
1332 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1334 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1335 return FALSE;
1338 /***********************************************************************
1339 * GetAspectRatioFilterEx (GDI32.142)
1341 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1343 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1344 return FALSE;
1347 /***********************************************************************
1348 * GetCharABCWidths16 (GDI.307)
1350 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1351 LPABC16 abc )
1353 ABC abc32;
1354 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1355 abc->abcA = abc32.abcA;
1356 abc->abcB = abc32.abcB;
1357 abc->abcC = abc32.abcC;
1358 return TRUE;
1362 /***********************************************************************
1363 * GetCharABCWidthsA (GDI32.149)
1365 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1366 LPABC abc )
1368 return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1372 /******************************************************************************
1373 * GetCharABCWidthsW [GDI32.152] Retrieves widths of characters in range
1375 * PARAMS
1376 * hdc [I] Handle of device context
1377 * firstChar [I] First character in range to query
1378 * lastChar [I] Last character in range to query
1379 * abc [O] Address of character-width structure
1381 * NOTES
1382 * Only works with TrueType fonts
1384 * RETURNS
1385 * Success: TRUE
1386 * Failure: FALSE
1388 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1389 LPABC abc )
1391 /* No TrueType fonts in Wine so far */
1392 FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1393 return FALSE;
1397 /***********************************************************************
1398 * GetGlyphOutline16 (GDI.309)
1400 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1401 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1402 LPVOID lpBuffer, const MAT2 *lpmat2 )
1404 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1405 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1406 return (DWORD)-1; /* failure */
1410 /***********************************************************************
1411 * GetGlyphOutlineA (GDI32.186)
1413 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1414 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1415 LPVOID lpBuffer, const MAT2 *lpmat2 )
1417 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1418 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1419 return (DWORD)-1; /* failure */
1422 /***********************************************************************
1423 * GetGlyphOutlineW (GDI32.187)
1425 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1426 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1427 LPVOID lpBuffer, const MAT2 *lpmat2 )
1429 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1430 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1431 return (DWORD)-1; /* failure */
1434 /***********************************************************************
1435 * CreateScalableFontResource16 (GDI.310)
1437 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1438 LPCSTR lpszResourceFile,
1439 LPCSTR fontFile, LPCSTR path )
1441 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1442 fontFile, path );
1445 /***********************************************************************
1446 * CreateScalableFontResourceA (GDI32.62)
1448 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1449 LPCSTR lpszResourceFile,
1450 LPCSTR lpszFontFile,
1451 LPCSTR lpszCurrentPath )
1453 /* fHidden=1 - only visible for the calling app, read-only, not
1454 * enumbered with EnumFonts/EnumFontFamilies
1455 * lpszCurrentPath can be NULL
1457 FIXME("(%ld,%s,%s,%s): stub\n",
1458 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1459 return FALSE; /* create failed */
1462 /***********************************************************************
1463 * CreateScalableFontResourceW (GDI32.63)
1465 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1466 LPCWSTR lpszResourceFile,
1467 LPCWSTR lpszFontFile,
1468 LPCWSTR lpszCurrentPath )
1470 FIXME("(%ld,%p,%p,%p): stub\n",
1471 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1472 return FALSE; /* create failed */
1476 /*************************************************************************
1477 * GetRasterizerCaps16 (GDI.313)
1479 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1481 return GetRasterizerCaps( lprs, cbNumBytes );
1485 /*************************************************************************
1486 * GetRasterizerCaps (GDI32.216)
1488 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1490 lprs->nSize = sizeof(RASTERIZER_STATUS);
1491 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1492 lprs->nLanguageID = 0;
1493 return TRUE;
1497 /*************************************************************************
1498 * GetKerningPairs16 (GDI.332)
1500 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1501 LPKERNINGPAIR16 lpKerningPairs )
1503 /* At this time kerning is ignored (set to 0) */
1504 int i;
1505 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1506 for (i = 0; i < cPairs; i++)
1507 lpKerningPairs[i].iKernAmount = 0;
1508 return 0;
1513 /*************************************************************************
1514 * GetKerningPairsA (GDI32.192)
1516 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1517 LPKERNINGPAIR lpKerningPairs )
1519 int i;
1520 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1521 for (i = 0; i < cPairs; i++)
1522 lpKerningPairs[i].iKernAmount = 0;
1523 return 0;
1527 /*************************************************************************
1528 * GetKerningPairsW (GDI32.193)
1530 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1531 LPKERNINGPAIR lpKerningPairs )
1533 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1536 /*************************************************************************
1537 * TranslateCharsetInfo [GDI32.382]
1539 * Fills a CHARSETINFO structure for a character set, code page, or
1540 * font. This allows making the correspondance between different labelings
1541 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1542 * of the same encoding.
1544 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1545 * only one codepage should be set in *lpSrc.
1547 * RETURNS
1548 * TRUE on success, FALSE on failure.
1551 BOOL WINAPI TranslateCharsetInfo(
1552 LPDWORD lpSrc, /* [in]
1553 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1554 if flags == TCI_SRCCHARSET: a character set value
1555 if flags == TCI_SRCCODEPAGE: a code page value
1557 LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1558 DWORD flags /* [in] determines interpretation of lpSrc */
1560 int index = 0;
1561 switch (flags) {
1562 case TCI_SRCFONTSIG:
1563 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1564 break;
1565 case TCI_SRCCODEPAGE:
1566 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1567 break;
1568 case TCI_SRCCHARSET:
1569 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1570 break;
1571 default:
1572 return FALSE;
1574 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1575 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1576 return TRUE;
1579 /*************************************************************************
1580 * GetFontLanguageInfo (GDI32.182)
1582 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1583 /* return value 0 is correct for most cases anyway */
1584 FIXME("(%x):stub!\n", hdc);
1585 return 0;
1588 /*************************************************************************
1589 * GetFontLanguageInfo (GDI.616)
1591 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1592 /* return value 0 is correct for most cases anyway */
1593 FIXME("(%x):stub!\n",hdc);
1594 return 0;
1597 /*************************************************************************
1598 * GetFontData [GDI32.181] Retrieve data for TrueType font
1600 * RETURNS
1602 * success: Number of bytes returned
1603 * failure: GDI_ERROR
1605 * NOTES
1607 * Calls SetLastError()
1609 * BUGS
1611 * Unimplemented
1613 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1614 LPVOID buffer, DWORD length)
1616 FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1617 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1618 return GDI_ERROR;
1621 /*************************************************************************
1622 * GetFontData16 [GDI.311]
1625 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1626 LPVOID lpvBuffer, DWORD cbData)
1628 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1631 /*************************************************************************
1632 * GetCharacterPlacementA [GDI32.160]
1634 * NOTES:
1635 * the web browser control of ie4 calls this with dwFlags=0
1637 DWORD WINAPI
1638 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1639 INT nMaxExtent, GCP_RESULTSA *lpResults,
1640 DWORD dwFlags)
1642 DWORD ret=0;
1643 SIZE size;
1645 TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1646 debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1648 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1649 "lpOutString=%p lpGlyphs=%p\n",
1650 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1651 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1653 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
1654 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
1655 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1656 if(lpResults->lpClass) FIXME("classes not implemented\n");
1657 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
1659 /* copy will do if the GCP_REORDER flag is not set */
1660 if(lpResults->lpOutString)
1662 lstrcpynA(lpResults->lpOutString, lpString, uCount);
1665 if (lpResults->lpDx)
1667 int i, c;
1668 for (i=0; i<uCount;i++)
1670 if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1671 lpResults->lpDx[i]= c;
1675 if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1676 ret = MAKELONG(size.cx, size.cy);
1678 return ret;
1681 /*************************************************************************
1682 * GetCharacterPlacementW [GDI32.161]
1684 DWORD WINAPI
1685 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1686 INT nMaxExtent, GCP_RESULTSW *lpResults,
1687 DWORD dwFlags)
1689 /* return value 0 is correct for most cases anyway */
1690 FIXME(":stub!\n");
1691 return 0;
1694 /*************************************************************************
1695 * GetCharABCWidthsFloatA [GDI32.150]
1697 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1698 LPABCFLOAT lpABCF)
1700 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1701 return 0;
1704 /*************************************************************************
1705 * GetCharABCWidthsFloatW [GDI32.151]
1707 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1708 UINT iLastChar, LPABCFLOAT lpABCF)
1710 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1711 return 0;
1714 /*************************************************************************
1715 * GetCharWidthFloatA [GDI32.156]
1717 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1718 UINT iLastChar, PFLOAT pxBuffer)
1720 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1721 return 0;
1724 /*************************************************************************
1725 * GetCharWidthFloatW [GDI32.157]
1727 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1728 UINT iLastChar, PFLOAT pxBuffer)
1730 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1731 return 0;
1735 /***********************************************************************
1737 * Font Resource API *
1739 ***********************************************************************/
1740 /***********************************************************************
1741 * AddFontResource16 (GDI.119)
1743 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1745 * FIXME: Load header and find the best-matching font in the fontList;
1746 * fixup dfPoints if all metrics are identical, otherwise create
1747 * new fontAlias. When soft font support is ready this will
1748 * simply create a new fontResource ('filename' will go into
1749 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
1750 * flag set.
1752 INT16 WINAPI AddFontResource16( LPCSTR filename )
1754 return AddFontResourceA( filename );
1758 /***********************************************************************
1759 * AddFontResourceA (GDI32.2)
1761 INT WINAPI AddFontResourceA( LPCSTR str )
1763 FIXME("(%s): stub! Read the Wine User Guide on how to install "
1764 "this font manually.\n", debugres_a(str));
1765 return 1;
1769 /***********************************************************************
1770 * AddFontResourceW (GDI32.4)
1772 INT WINAPI AddFontResourceW( LPCWSTR str )
1774 FIXME("(%s): stub! Read the Wine User Guide on how to install "
1775 "this font manually.\n", debugres_w(str));
1776 return 1;
1779 /***********************************************************************
1780 * RemoveFontResource16 (GDI.136)
1782 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
1784 FIXME("(%s): stub\n", debugres_a(str));
1785 return TRUE;
1789 /***********************************************************************
1790 * RemoveFontResourceA (GDI32.284)
1792 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1794 /* This is how it should look like */
1796 fontResource** ppfr;
1797 BOOL32 retVal = FALSE;
1799 EnterCriticalSection( &crtsc_fonts_X11 );
1800 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1801 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1803 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1804 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1806 if( (*ppfr)->fo_count )
1807 (*ppfr)->fr_flags |= FR_REMOVED;
1808 else
1809 XFONT_RemoveFontResource( ppfr );
1811 retVal = TRUE;
1813 LeaveCriticalSection( &crtsc_fonts_X11 );
1814 return retVal;
1816 FIXME("(%s): stub\n", debugres_a(str));
1817 return TRUE;
1821 /***********************************************************************
1822 * RemoveFontResourceW (GDI32.286)
1824 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1826 FIXME("(%s): stub\n", debugres_w(str) );
1827 return TRUE;