Some more ListView_ macros, winelib fixes.
[wine/hacks.git] / objects / font.c
blobe662b7be1f832ef4a8157a5eeaf73e2e8f69be9c
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 "wine/winestring.h"
11 #include "font.h"
12 #include "heap.h"
13 #include "metafile.h"
14 #include "options.h"
15 #include "debugtools.h"
16 #include "winerror.h"
17 #include "dc.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 lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
131 void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONTA font32 )
133 font32->lfHeight = font16->lfHeight;
134 font32->lfWidth = font16->lfWidth;
135 font32->lfEscapement = font16->lfEscapement;
136 font32->lfOrientation = font16->lfOrientation;
137 font32->lfWeight = font16->lfWeight;
138 font32->lfItalic = font16->lfItalic;
139 font32->lfUnderline = font16->lfUnderline;
140 font32->lfStrikeOut = font16->lfStrikeOut;
141 font32->lfCharSet = font16->lfCharSet;
142 font32->lfOutPrecision = font16->lfOutPrecision;
143 font32->lfClipPrecision = font16->lfClipPrecision;
144 font32->lfQuality = font16->lfQuality;
145 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
146 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
149 void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONTW font32 )
151 font32->lfHeight = font16->lfHeight;
152 font32->lfWidth = font16->lfWidth;
153 font32->lfEscapement = font16->lfEscapement;
154 font32->lfOrientation = font16->lfOrientation;
155 font32->lfWeight = font16->lfWeight;
156 font32->lfItalic = font16->lfItalic;
157 font32->lfUnderline = font16->lfUnderline;
158 font32->lfStrikeOut = font16->lfStrikeOut;
159 font32->lfCharSet = font16->lfCharSet;
160 font32->lfOutPrecision = font16->lfOutPrecision;
161 font32->lfClipPrecision = font16->lfClipPrecision;
162 font32->lfQuality = font16->lfQuality;
163 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
164 lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
167 void FONT_EnumLogFontEx16To32A( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXA font32 )
169 FONT_LogFont16To32A( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
170 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
171 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
172 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
175 void FONT_EnumLogFontEx16To32W( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXW font32 )
177 FONT_LogFont16To32W( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
178 lstrcpynAtoW( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
179 lstrcpynAtoW( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
180 lstrcpynAtoW( font32->elfScript, font16->elfScript, LF_FACESIZE );
183 /***********************************************************************
184 * TEXTMETRIC conversion functions.
186 void FONT_TextMetric32Ato16(const LPTEXTMETRICA ptm32, LPTEXTMETRIC16 ptm16 )
188 ptm16->tmHeight = ptm32->tmHeight;
189 ptm16->tmAscent = ptm32->tmAscent;
190 ptm16->tmDescent = ptm32->tmDescent;
191 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
192 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
193 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
194 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
195 ptm16->tmWeight = ptm32->tmWeight;
196 ptm16->tmOverhang = ptm32->tmOverhang;
197 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
198 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
199 ptm16->tmFirstChar = ptm32->tmFirstChar;
200 ptm16->tmLastChar = ptm32->tmLastChar;
201 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
202 ptm16->tmBreakChar = ptm32->tmBreakChar;
203 ptm16->tmItalic = ptm32->tmItalic;
204 ptm16->tmUnderlined = ptm32->tmUnderlined;
205 ptm16->tmStruckOut = ptm32->tmStruckOut;
206 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
207 ptm16->tmCharSet = ptm32->tmCharSet;
210 void FONT_TextMetric32Wto16(const LPTEXTMETRICW ptm32, LPTEXTMETRIC16 ptm16 )
212 ptm16->tmHeight = ptm32->tmHeight;
213 ptm16->tmAscent = ptm32->tmAscent;
214 ptm16->tmDescent = ptm32->tmDescent;
215 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
216 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
217 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
218 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
219 ptm16->tmWeight = ptm32->tmWeight;
220 ptm16->tmOverhang = ptm32->tmOverhang;
221 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
222 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
223 ptm16->tmFirstChar = ptm32->tmFirstChar;
224 ptm16->tmLastChar = ptm32->tmLastChar;
225 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
226 ptm16->tmBreakChar = ptm32->tmBreakChar;
227 ptm16->tmItalic = ptm32->tmItalic;
228 ptm16->tmUnderlined = ptm32->tmUnderlined;
229 ptm16->tmStruckOut = ptm32->tmStruckOut;
230 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
231 ptm16->tmCharSet = ptm32->tmCharSet;
234 void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICA ptm32 )
236 ptm32->tmHeight = ptm16->tmHeight;
237 ptm32->tmAscent = ptm16->tmAscent;
238 ptm32->tmDescent = ptm16->tmDescent;
239 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
240 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
241 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
242 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
243 ptm32->tmWeight = ptm16->tmWeight;
244 ptm32->tmOverhang = ptm16->tmOverhang;
245 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
246 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
247 ptm32->tmFirstChar = ptm16->tmFirstChar;
248 ptm32->tmLastChar = ptm16->tmLastChar;
249 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
250 ptm32->tmBreakChar = ptm16->tmBreakChar;
251 ptm32->tmItalic = ptm16->tmItalic;
252 ptm32->tmUnderlined = ptm16->tmUnderlined;
253 ptm32->tmStruckOut = ptm16->tmStruckOut;
254 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
255 ptm32->tmCharSet = ptm16->tmCharSet;
258 void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICW ptm32 )
260 ptm32->tmHeight = ptm16->tmHeight;
261 ptm32->tmAscent = ptm16->tmAscent;
262 ptm32->tmDescent = ptm16->tmDescent;
263 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
264 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
265 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
266 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
267 ptm32->tmWeight = ptm16->tmWeight;
268 ptm32->tmOverhang = ptm16->tmOverhang;
269 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
270 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
271 ptm32->tmFirstChar = ptm16->tmFirstChar;
272 ptm32->tmLastChar = ptm16->tmLastChar;
273 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
274 ptm32->tmBreakChar = ptm16->tmBreakChar;
275 ptm32->tmItalic = ptm16->tmItalic;
276 ptm32->tmUnderlined = ptm16->tmUnderlined;
277 ptm32->tmStruckOut = ptm16->tmStruckOut;
278 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
279 ptm32->tmCharSet = ptm16->tmCharSet;
282 void FONT_TextMetric32Ato32W(const LPTEXTMETRICA ptm32A, LPTEXTMETRICW ptm32W )
284 ptm32W->tmHeight = ptm32A->tmHeight;
285 ptm32W->tmAscent = ptm32A->tmAscent;
286 ptm32W->tmDescent = ptm32A->tmDescent;
287 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
288 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
289 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
290 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
291 ptm32W->tmWeight = ptm32A->tmWeight;
292 ptm32W->tmOverhang = ptm32A->tmOverhang;
293 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
294 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
295 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
296 ptm32W->tmLastChar = ptm32A->tmLastChar;
297 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
298 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
299 ptm32W->tmItalic = ptm32A->tmItalic;
300 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
301 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
302 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
303 ptm32W->tmCharSet = ptm32A->tmCharSet;
306 /***********************************************************************
307 * CreateFontIndirect16 (GDI.57)
309 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
311 HFONT16 hFont = 0;
313 if (font)
315 hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
316 if( hFont )
318 FONTOBJ* fontPtr;
319 fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont );
320 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
322 TRACE("(%i %i %i %i) '%s' %s %s => %04x\n",
323 font->lfHeight, font->lfWidth,
324 font->lfEscapement, font->lfOrientation,
325 font->lfFaceName ? font->lfFaceName : "NULL",
326 font->lfWeight > 400 ? "Bold" : "",
327 font->lfItalic ? "Italic" : "", hFont);
329 if (font->lfEscapement != font->lfOrientation) {
330 /* this should really depend on whether GM_ADVANCED is set */
331 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
332 WARN("orientation angle %f set to "
333 "escapement angle %f for new font %04x\n",
334 font->lfOrientation/10., font->lfEscapement/10., hFont);
336 GDI_HEAP_UNLOCK( hFont );
339 else WARN("(NULL) => NULL\n");
341 return hFont;
344 /***********************************************************************
345 * CreateFontIndirectA (GDI32.44)
347 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *font )
349 LOGFONT16 font16;
351 FONT_LogFont32ATo16( font, &font16 );
352 return CreateFontIndirect16( &font16 );
355 /***********************************************************************
356 * CreateFontIndirectW (GDI32.45)
358 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *font )
360 LOGFONT16 font16;
362 FONT_LogFont32WTo16( font, &font16 );
363 return CreateFontIndirect16( &font16 );
366 /***********************************************************************
367 * CreateFont16 (GDI.56)
369 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
370 INT16 weight, BYTE italic, BYTE underline,
371 BYTE strikeout, BYTE charset, BYTE outpres,
372 BYTE clippres, BYTE quality, BYTE pitch,
373 LPCSTR name )
375 LOGFONT16 logfont;
377 TRACE("('%s',%d,%d)\n", (name ? name : "(null)") , height, width);
379 logfont.lfHeight = height;
380 logfont.lfWidth = width;
381 logfont.lfEscapement = esc;
382 logfont.lfOrientation = orient;
383 logfont.lfWeight = weight;
384 logfont.lfItalic = italic;
385 logfont.lfUnderline = underline;
386 logfont.lfStrikeOut = strikeout;
387 logfont.lfCharSet = charset;
388 logfont.lfOutPrecision = outpres;
389 logfont.lfClipPrecision = clippres;
390 logfont.lfQuality = quality;
391 logfont.lfPitchAndFamily = pitch;
393 if (name)
394 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
395 else
396 logfont.lfFaceName[0] = '\0';
398 return CreateFontIndirect16( &logfont );
401 /*************************************************************************
402 * CreateFontA (GDI32.43)
404 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
405 INT orient, INT weight, DWORD italic,
406 DWORD underline, DWORD strikeout, DWORD charset,
407 DWORD outpres, DWORD clippres, DWORD quality,
408 DWORD pitch, LPCSTR name )
410 return (HFONT)CreateFont16( height, width, esc, orient, weight, italic,
411 underline, strikeout, charset, outpres,
412 clippres, quality, pitch, name );
415 /*************************************************************************
416 * CreateFontW (GDI32.46)
418 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
419 INT orient, INT weight, DWORD italic,
420 DWORD underline, DWORD strikeout, DWORD charset,
421 DWORD outpres, DWORD clippres, DWORD quality,
422 DWORD pitch, LPCWSTR name )
424 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
425 HFONT ret = (HFONT)CreateFont16( height, width, esc, orient, weight,
426 italic, underline, strikeout, charset,
427 outpres, clippres, quality, pitch,
428 namea );
429 if (namea) HeapFree( GetProcessHeap(), 0, namea );
430 return ret;
434 /***********************************************************************
435 * FONT_GetObject16
437 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
439 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
440 memcpy( buffer, &font->logfont, count );
441 return count;
444 /***********************************************************************
445 * FONT_GetObjectA
447 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
449 LOGFONTA fnt32;
451 FONT_LogFont16To32A( &font->logfont, &fnt32 );
453 if (count > sizeof(fnt32)) count = sizeof(fnt32);
454 memcpy( buffer, &fnt32, count );
455 return count;
457 /***********************************************************************
458 * FONT_GetObjectW
460 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
462 LOGFONTW fnt32;
464 FONT_LogFont16To32W( &font->logfont, &fnt32 );
466 if (count > sizeof(fnt32)) count = sizeof(fnt32);
467 memcpy( buffer, &fnt32, count );
468 return count;
472 /***********************************************************************
473 * FONT_EnumInstance16
475 * Called by the device driver layer to pass font info
476 * down to the application.
478 static INT FONT_EnumInstance16( LPENUMLOGFONTEX16 plf,
479 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
481 #define pfe ((fontEnum16*)lp)
482 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
483 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
485 memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
486 memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
488 return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
490 #undef pfe
491 return 1;
494 /***********************************************************************
495 * FONT_EnumInstance
497 static INT FONT_EnumInstance( LPENUMLOGFONTEX16 plf,
498 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
500 /* lfCharSet is at the same offset in both LOGFONT32A and LOGFONT32W */
502 #define pfe ((fontEnum32*)lp)
503 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
504 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
506 /* convert font metrics */
508 if( pfe->dwFlags & ENUM_UNICODE )
510 FONT_EnumLogFontEx16To32W( plf, pfe->lpLogFont );
511 FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICW)(pfe->lpTextMetric) );
513 return pfe->lpEnumFunc( pfe->lpLogFont, pfe->lpTextMetric, fType, pfe->lpData );
515 else
517 ENUMLOGFONTEXA logfont;
519 FONT_EnumLogFontEx16To32A( plf, &logfont);
520 FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICA)pfe->lpTextMetric );
522 return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
523 pfe->lpTextMetric, fType, pfe->lpData );
526 #undef pfe
527 return 1;
530 /***********************************************************************
531 * EnumFontFamiliesEx16 (GDI.613)
533 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
534 FONTENUMPROCEX16 efproc, LPARAM lParam,
535 DWORD dwFlags)
537 INT16 retVal = 0;
538 DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
540 if( dc && dc->funcs->pEnumDeviceFonts )
542 LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
543 if( lptm16 )
545 LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
546 if( lplf16 )
548 fontEnum16 fe16;
550 fe16.lpLogFontParam = plf;
551 fe16.lpEnumFunc = efproc;
552 fe16.lpData = lParam;
554 fe16.lpTextMetric = lptm16;
555 fe16.lpLogFont = lplf16;
556 fe16.segTextMetric = SEGPTR_GET(lptm16);
557 fe16.segLogFont = SEGPTR_GET(lplf16);
559 retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
561 SEGPTR_FREE(lplf16);
563 SEGPTR_FREE(lptm16);
566 return retVal;
569 /***********************************************************************
570 * FONT_EnumFontFamiliesEx
572 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc,
573 LPARAM lParam, DWORD dwUnicode)
575 DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
577 if( dc && dc->funcs->pEnumDeviceFonts )
579 LOGFONT16 lf16;
580 NEWTEXTMETRICEXW tm32w;
581 ENUMLOGFONTEXW lf32w;
582 fontEnum32 fe32;
584 fe32.lpLogFontParam = plf;
585 fe32.lpEnumFunc = efproc;
586 fe32.lpData = lParam;
588 fe32.lpTextMetric = &tm32w;
589 fe32.lpLogFont = &lf32w;
590 fe32.dwFlags = dwUnicode;
592 /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
594 if( plf->lfFaceName[0] )
596 if( dwUnicode )
597 lstrcpynWtoA( lf16.lfFaceName, plf->lfFaceName, LF_FACESIZE );
598 else
599 lstrcpynA( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
601 else lf16.lfFaceName[0] = '\0';
602 lf16.lfCharSet = plf->lfCharSet;
604 return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
606 return 0;
609 /***********************************************************************
610 * EnumFontFamiliesExW (GDI32.82)
612 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
613 FONTENUMPROCEXW efproc,
614 LPARAM lParam, DWORD dwFlags )
616 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
619 /***********************************************************************
620 * EnumFontFamiliesExA (GDI32.81)
622 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
623 FONTENUMPROCEXA efproc,
624 LPARAM lParam, DWORD dwFlags)
626 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)plf,
627 (FONTENUMPROCEXW)efproc, lParam, 0);
630 /***********************************************************************
631 * EnumFontFamilies16 (GDI.330)
633 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
634 FONTENUMPROC16 efproc, LPARAM lpData )
636 LOGFONT16 lf;
638 lf.lfCharSet = DEFAULT_CHARSET;
639 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
640 else lf.lfFaceName[0] = '\0';
642 return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
645 /***********************************************************************
646 * EnumFontFamiliesA (GDI32.80)
648 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
649 FONTENUMPROCA efproc, LPARAM lpData )
651 LOGFONTA lf;
653 lf.lfCharSet = DEFAULT_CHARSET;
654 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
655 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
657 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)&lf,
658 (FONTENUMPROCEXW)efproc, lpData, 0 );
661 /***********************************************************************
662 * EnumFontFamiliesW (GDI32.83)
664 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
665 FONTENUMPROCW efproc, LPARAM lpData )
667 LOGFONTW lf;
669 lf.lfCharSet = DEFAULT_CHARSET;
670 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
671 else lf.lfFaceName[0] = 0;
673 return FONT_EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROCEXW)efproc,
674 lpData, ENUM_UNICODE );
677 /***********************************************************************
678 * EnumFonts16 (GDI.70)
680 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
681 LPARAM lpData )
683 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
686 /***********************************************************************
687 * EnumFontsA (GDI32.84)
689 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
690 LPARAM lpData )
692 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
695 /***********************************************************************
696 * EnumFontsW (GDI32.85)
698 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
699 LPARAM lpData )
701 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
705 /***********************************************************************
706 * GetTextCharacterExtra16 (GDI.89)
708 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
710 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
711 if (!dc) return 0;
712 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
713 / dc->vportExtX );
717 /***********************************************************************
718 * GetTextCharacterExtra (GDI32.225)
720 INT WINAPI GetTextCharacterExtra( HDC hdc )
722 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
723 if (!dc) return 0;
724 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
725 / dc->vportExtX );
729 /***********************************************************************
730 * SetTextCharacterExtra16 (GDI.8)
732 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
734 return (INT16)SetTextCharacterExtra( hdc, extra );
738 /***********************************************************************
739 * SetTextCharacterExtra (GDI32.337)
741 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
743 INT prev;
744 DC * dc = DC_GetDCPtr( hdc );
745 if (!dc) return 0;
746 if (dc->funcs->pSetTextCharacterExtra)
747 return dc->funcs->pSetTextCharacterExtra( dc, extra );
748 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
749 prev = dc->w.charExtra;
750 dc->w.charExtra = abs(extra);
751 return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
755 /***********************************************************************
756 * SetTextJustification16 (GDI.10)
758 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
760 return SetTextJustification( hdc, extra, breaks );
764 /***********************************************************************
765 * SetTextJustification (GDI32.339)
767 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
769 DC * dc = DC_GetDCPtr( hdc );
770 if (!dc) return 0;
771 if (dc->funcs->pSetTextJustification)
772 return dc->funcs->pSetTextJustification( dc, extra, breaks );
774 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
775 if (!extra) breaks = 0;
776 dc->w.breakTotalExtra = extra;
777 dc->w.breakCount = breaks;
778 if (breaks)
780 dc->w.breakExtra = extra / breaks;
781 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
783 else
785 dc->w.breakExtra = 0;
786 dc->w.breakRem = 0;
788 return 1;
792 /***********************************************************************
793 * GetTextFace16 (GDI.92)
795 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
797 return GetTextFaceA(hdc,count,name);
800 /***********************************************************************
801 * GetTextFaceA (GDI32.234)
803 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
805 FONTOBJ *font;
807 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
808 if (!dc) return 0;
809 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
810 return 0;
811 if (name)
812 lstrcpynA( name, font->logfont.lfFaceName, count );
813 GDI_HEAP_UNLOCK( dc->w.hFont );
814 if (name)
815 return strlen(name);
816 else
817 return strlen(font->logfont.lfFaceName) + 1;
820 /***********************************************************************
821 * GetTextFaceW (GDI32.235)
823 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
825 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
826 INT res = GetTextFaceA(hdc,count,nameA);
827 lstrcpyAtoW( name, nameA );
828 HeapFree( GetProcessHeap(), 0, nameA );
829 return res;
833 /***********************************************************************
834 * GetTextExtent16 (GDI.91)
836 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
838 SIZE16 size;
839 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
840 return MAKELONG( size.cx, size.cy );
844 /***********************************************************************
845 * GetTextExtentPoint16 (GDI.471)
847 * FIXME: Should this have a bug for compatibility?
848 * Original Windows versions of GetTextExtentPoint{A,W} have documented
849 * bugs (-> MSDN KB q147647.txt).
851 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
852 LPSIZE16 size )
854 SIZE size32;
855 BOOL ret;
856 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count,
857 size);
858 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
859 CONV_SIZE32TO16( &size32, size );
860 return (BOOL16)ret;
864 /***********************************************************************
865 * GetTextExtentPoint32A (GDI32.230)
867 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
868 LPSIZE size )
870 LPWSTR p;
871 BOOL ret;
873 /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
874 * We allocate one more than we need so that lstrcpynWtoA can write a
875 * trailing 0 if it wants.
878 p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
879 lstrcpynAtoW(p, str, count+1);
880 ret = GetTextExtentPoint32W( hdc, p, count, size );
881 HeapFree( GetProcessHeap(), 0, p );
882 return ret;
886 /***********************************************************************
887 * GetTextExtentPoint32W [GDI32.231] Computes width/height for a string
889 * Computes width and height of the specified string.
891 * RETURNS
892 * Success: TRUE
893 * Failure: FALSE
895 BOOL WINAPI GetTextExtentPoint32W(
896 HDC hdc, /* [in] Handle of device context */
897 LPCWSTR str, /* [in] Address of text string */
898 INT count, /* [in] Number of characters in string */
899 LPSIZE size) /* [out] Address of structure for string size */
901 DC * dc = DC_GetDCPtr( hdc );
902 if (!dc || !dc->funcs->pGetTextExtentPoint ||
903 !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
904 return FALSE;
906 TRACE("(%08x %s %d %p): returning %d,%d\n",
907 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
908 return TRUE;
912 /***********************************************************************
913 * GetTextExtentPointA (GDI32.232)
915 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
916 LPSIZE size )
918 TRACE("not bug compatible.\n");
919 return GetTextExtentPoint32A( hdc, str, count, size );
922 /***********************************************************************
923 * GetTextExtentPointW (GDI32.233)
925 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
926 LPSIZE size )
928 TRACE("not bug compatible.\n");
929 return GetTextExtentPoint32W( hdc, str, count, size );
933 /***********************************************************************
934 * GetTextExtentExPointA (GDI32.228)
936 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
937 INT maxExt, LPINT lpnFit,
938 LPINT alpDx, LPSIZE size )
940 LPWSTR p;
941 BOOL ret;
943 /* Docs say str should be 0 terminated here, but we'll use count just in case
946 p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
947 lstrcpynAtoW(p, str, count+1);
948 ret = GetTextExtentExPointW( hdc, p, count, maxExt, lpnFit, alpDx, size);
949 HeapFree( GetProcessHeap(), 0, p );
950 return ret;
954 /***********************************************************************
955 * GetTextExtentExPointW (GDI32.229)
958 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
959 INT maxExt, LPINT lpnFit,
960 LPINT alpDx, LPSIZE size )
962 int index, nFit, extent;
963 SIZE tSize;
964 DC * dc = DC_GetDCPtr( hdc );
966 if (!dc || !dc->funcs->pGetTextExtentPoint) return FALSE;
968 size->cx = size->cy = nFit = extent = 0;
969 for(index = 0; index < count; index++)
971 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
972 if( extent+tSize.cx < maxExt )
974 extent+=tSize.cx;
975 nFit++;
976 str++;
977 if( alpDx ) alpDx[index] = extent;
978 if( tSize.cy > size->cy ) size->cy = tSize.cy;
980 else break;
982 size->cx = extent;
983 *lpnFit = nFit;
985 TRACE("(%08x %s %d) returning %d %d %d\n",
986 hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
987 return TRUE;
990 /***********************************************************************
991 * GetTextMetrics16 (GDI.93)
993 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
995 TEXTMETRICA tm32;
997 if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
998 FONT_TextMetric32Ato16( &tm32, metrics );
999 return TRUE;
1003 /***********************************************************************
1004 * GetTextMetricsA (GDI32.236)
1006 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1008 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1009 if (!dc)
1011 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
1012 return FALSE;
1015 if (!dc->funcs->pGetTextMetrics ||
1016 !dc->funcs->pGetTextMetrics( dc, metrics ))
1017 return FALSE;
1019 /* device layer returns values in device units
1020 * therefore we have to convert them to logical */
1022 #define WDPTOLP(x) ((x<0)? \
1023 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1024 (abs((x)*dc->wndExtX/dc->vportExtX)))
1025 #define HDPTOLP(y) ((y<0)? \
1026 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1027 (abs((y)*dc->wndExtY/dc->vportExtY)))
1029 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1030 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1031 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1032 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1033 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1034 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1035 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1036 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1038 TRACE("text metrics:\n"
1039 " Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1040 " Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1041 " UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1042 " StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1043 " PitchAndFamily = %02x\n"
1044 " --------------------\n"
1045 " InternalLeading = %li\n"
1046 " Ascent = %li\n"
1047 " Descent = %li\n"
1048 " Height = %li\n",
1049 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1050 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1051 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1052 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1053 metrics->tmPitchAndFamily,
1054 metrics->tmInternalLeading,
1055 metrics->tmAscent,
1056 metrics->tmDescent,
1057 metrics->tmHeight );
1058 return TRUE;
1062 /***********************************************************************
1063 * GetTextMetricsW (GDI32.237)
1065 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1067 TEXTMETRICA tm;
1068 if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1069 FONT_TextMetric32Ato32W( &tm, metrics );
1070 return TRUE;
1074 /***********************************************************************
1075 * GetOutlineTextMetrics16 [GDI.308] Gets metrics for TrueType fonts.
1077 * NOTES
1078 * lpOTM should be LPOUTLINETEXTMETRIC
1080 * RETURNS
1081 * Success: Non-zero or size of required buffer
1082 * Failure: 0
1084 UINT16 WINAPI GetOutlineTextMetrics16(
1085 HDC16 hdc, /* [in] Handle of device context */
1086 UINT16 cbData, /* [in] Size of metric data array */
1087 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1089 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1090 return 0;
1094 /***********************************************************************
1095 * GetOutlineTextMetricsA [GDI.207] Gets metrics for TrueType fonts.
1098 * RETURNS
1099 * Success: Non-zero or size of required buffer
1100 * Failure: 0
1102 UINT WINAPI GetOutlineTextMetricsA(
1103 HDC hdc, /* [in] Handle of device context */
1104 UINT cbData, /* [in] Size of metric data array */
1105 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1109 UINT rtn = FALSE;
1110 LPTEXTMETRICA lptxtMetr;
1114 if (lpOTM == 0)
1117 lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1118 rtn = sizeof(OUTLINETEXTMETRICA);
1119 cbData = rtn;
1120 } else
1122 cbData = sizeof(*lpOTM);
1123 rtn = cbData;
1126 lpOTM->otmSize = cbData;
1128 lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1130 if (!GetTextMetricsA(hdc,lptxtMetr))
1132 return 0;
1133 } else
1135 memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1138 HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1140 lpOTM->otmFilter = 0;
1142 lpOTM->otmPanoseNumber.bFamilyType = 0;
1143 lpOTM->otmPanoseNumber.bSerifStyle = 0;
1144 lpOTM->otmPanoseNumber.bWeight = 0;
1145 lpOTM->otmPanoseNumber.bProportion = 0;
1146 lpOTM->otmPanoseNumber.bContrast = 0;
1147 lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1148 lpOTM->otmPanoseNumber.bArmStyle = 0;
1149 lpOTM->otmPanoseNumber.bLetterform = 0;
1150 lpOTM->otmPanoseNumber.bMidline = 0;
1151 lpOTM->otmPanoseNumber.bXHeight = 0;
1153 lpOTM->otmfsSelection = 0;
1154 lpOTM->otmfsType = 0;
1157 Further fill of the structure not implemented,
1158 Needs real values for the structure members
1161 return rtn;
1164 /***********************************************************************
1165 * GetOutlineTextMetricsW [GDI32.208]
1167 UINT WINAPI GetOutlineTextMetricsW(
1168 HDC hdc, /* [in] Handle of device context */
1169 UINT cbData, /* [in] Size of metric data array */
1170 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1172 FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1173 return 0;
1176 /***********************************************************************
1177 * GetCharWidth16 (GDI.350)
1179 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1180 LPINT16 buffer )
1182 BOOL retVal = FALSE;
1184 if( firstChar != lastChar )
1186 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1187 sizeof(INT)*(1 + (lastChar - firstChar)));
1188 if( buf32 )
1190 LPINT obuf32 = buf32;
1191 int i;
1193 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1194 if (retVal)
1196 for (i = firstChar; i <= lastChar; i++)
1197 *buffer++ = *buf32++;
1199 HeapFree(GetProcessHeap(), 0, obuf32);
1202 else /* happens quite often to warrant a special treatment */
1204 INT chWidth;
1205 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1206 *buffer = chWidth;
1208 return retVal;
1212 /***********************************************************************
1213 * GetCharWidth32A (GDI32.155)
1215 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1216 LPINT buffer )
1218 UINT i, extra;
1219 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1220 if (!dc)
1222 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
1223 return FALSE;
1226 if (!dc->funcs->pGetCharWidth ||
1227 !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1228 return FALSE;
1230 /* convert device units to logical */
1232 extra = dc->vportExtX >> 1;
1233 for( i = firstChar; i <= lastChar; i++, buffer++ )
1234 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1236 return TRUE;
1240 /***********************************************************************
1241 * GetCharWidth32W (GDI32.158)
1243 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1244 LPINT buffer )
1246 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1251 /* FIXME: all following APIs *******************************************
1254 * SetMapperFlags16 (GDI.349)
1256 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1258 return SetMapperFlags( hDC, dwFlag );
1262 /***********************************************************************
1263 * SetMapperFlags (GDI32.322)
1265 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1267 DC *dc = DC_GetDCPtr( hDC );
1268 DWORD ret = 0;
1269 if(!dc) return 0;
1270 if(dc->funcs->pSetMapperFlags)
1271 ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1272 else
1273 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1274 GDI_HEAP_UNLOCK( hDC );
1275 return ret;
1278 /***********************************************************************
1279 * GetAspectRatioFilterEx16 (GDI.486)
1281 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1283 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1284 return FALSE;
1287 /***********************************************************************
1288 * GetAspectRatioFilterEx (GDI32.142)
1290 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1292 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1293 return FALSE;
1296 /***********************************************************************
1297 * GetCharABCWidths16 (GDI.307)
1299 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1300 LPABC16 abc )
1302 ABC abc32;
1303 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1304 abc->abcA = abc32.abcA;
1305 abc->abcB = abc32.abcB;
1306 abc->abcC = abc32.abcC;
1307 return TRUE;
1311 /***********************************************************************
1312 * GetCharABCWidthsA (GDI32.149)
1314 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1315 LPABC abc )
1317 return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1321 /******************************************************************************
1322 * GetCharABCWidthsW [GDI32.152] Retrieves widths of characters in range
1324 * PARAMS
1325 * hdc [I] Handle of device context
1326 * firstChar [I] First character in range to query
1327 * lastChar [I] Last character in range to query
1328 * abc [O] Address of character-width structure
1330 * NOTES
1331 * Only works with TrueType fonts
1333 * RETURNS
1334 * Success: TRUE
1335 * Failure: FALSE
1337 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1338 LPABC abc )
1340 /* No TrueType fonts in Wine so far */
1341 FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1342 return FALSE;
1346 /***********************************************************************
1347 * GetGlyphOutline16 (GDI.309)
1349 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1350 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1351 LPVOID lpBuffer, const MAT2 *lpmat2 )
1353 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1354 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1355 return (DWORD)-1; /* failure */
1359 /***********************************************************************
1360 * GetGlyphOutlineA (GDI32.186)
1362 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1363 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1364 LPVOID lpBuffer, const MAT2 *lpmat2 )
1366 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1367 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1368 return (DWORD)-1; /* failure */
1371 /***********************************************************************
1372 * GetGlyphOutlineW (GDI32.187)
1374 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1375 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1376 LPVOID lpBuffer, const MAT2 *lpmat2 )
1378 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1379 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1380 return (DWORD)-1; /* failure */
1383 /***********************************************************************
1384 * CreateScalableFontResource16 (GDI.310)
1386 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1387 LPCSTR lpszResourceFile,
1388 LPCSTR fontFile, LPCSTR path )
1390 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1391 fontFile, path );
1394 /***********************************************************************
1395 * CreateScalableFontResourceA (GDI32.62)
1397 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1398 LPCSTR lpszResourceFile,
1399 LPCSTR lpszFontFile,
1400 LPCSTR lpszCurrentPath )
1402 /* fHidden=1 - only visible for the calling app, read-only, not
1403 * enumbered with EnumFonts/EnumFontFamilies
1404 * lpszCurrentPath can be NULL
1406 FIXME("(%ld,%s,%s,%s): stub\n",
1407 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1408 return FALSE; /* create failed */
1411 /***********************************************************************
1412 * CreateScalableFontResourceW (GDI32.63)
1414 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1415 LPCWSTR lpszResourceFile,
1416 LPCWSTR lpszFontFile,
1417 LPCWSTR lpszCurrentPath )
1419 FIXME("(%ld,%p,%p,%p): stub\n",
1420 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1421 return FALSE; /* create failed */
1425 /*************************************************************************
1426 * GetRasterizerCaps16 (GDI.313)
1428 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1430 return GetRasterizerCaps( lprs, cbNumBytes );
1434 /*************************************************************************
1435 * GetRasterizerCaps (GDI32.216)
1437 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1439 lprs->nSize = sizeof(RASTERIZER_STATUS);
1440 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1441 lprs->nLanguageID = 0;
1442 return TRUE;
1446 /*************************************************************************
1447 * GetKerningPairs16 (GDI.332)
1449 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1450 LPKERNINGPAIR16 lpKerningPairs )
1452 /* At this time kerning is ignored (set to 0) */
1453 int i;
1454 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1455 for (i = 0; i < cPairs; i++)
1456 lpKerningPairs[i].iKernAmount = 0;
1457 return 0;
1462 /*************************************************************************
1463 * GetKerningPairsA (GDI32.192)
1465 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1466 LPKERNINGPAIR lpKerningPairs )
1468 int i;
1469 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1470 for (i = 0; i < cPairs; i++)
1471 lpKerningPairs[i].iKernAmount = 0;
1472 return 0;
1476 /*************************************************************************
1477 * GetKerningPairsW (GDI32.193)
1479 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1480 LPKERNINGPAIR lpKerningPairs )
1482 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1485 /*************************************************************************
1486 * TranslateCharsetInfo [GDI32.382]
1488 * Fills a CHARSETINFO structure for a character set, code page, or
1489 * font. This allows making the correspondance between different labelings
1490 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1491 * of the same encoding.
1493 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1494 * only one codepage should be set in *lpSrc.
1496 * RETURNS
1497 * TRUE on success, FALSE on failure.
1500 BOOL WINAPI TranslateCharsetInfo(
1501 LPDWORD lpSrc, /*
1502 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1503 if flags == TCI_SRCCHARSET: a character set value
1504 if flags == TCI_SRCCODEPAGE: a code page value
1506 LPCHARSETINFO lpCs, /* structure to receive charset information */
1507 DWORD flags /* determines interpretation of lpSrc */
1509 int index = 0;
1510 switch (flags) {
1511 case TCI_SRCFONTSIG:
1512 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1513 break;
1514 case TCI_SRCCODEPAGE:
1515 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1516 break;
1517 case TCI_SRCCHARSET:
1518 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1519 break;
1520 default:
1521 return FALSE;
1523 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1524 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1525 return TRUE;
1528 /*************************************************************************
1529 * GetFontLanguageInfo (GDI32.182)
1531 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1532 /* return value 0 is correct for most cases anyway */
1533 FIXME("(%x):stub!\n", hdc);
1534 return 0;
1537 /*************************************************************************
1538 * GetFontLanguageInfo (GDI.616)
1540 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1541 /* return value 0 is correct for most cases anyway */
1542 FIXME("(%x):stub!\n",hdc);
1543 return 0;
1546 /*************************************************************************
1547 * GetFontData [GDI32.181] Retrieve data for TrueType font
1549 * RETURNS
1551 * success: Number of bytes returned
1552 * failure: GDI_ERROR
1554 * NOTES
1556 * Calls SetLastError()
1558 * BUGS
1560 * Unimplemented
1562 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1563 LPVOID buffer, DWORD length)
1565 FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1566 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1567 return GDI_ERROR;
1570 /*************************************************************************
1571 * GetFontData16 [GDI.311]
1574 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1575 LPVOID lpvBuffer, DWORD cbData)
1577 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1580 /*************************************************************************
1581 * GetCharacterPlacementA [GDI32.160]
1583 * NOTES:
1584 * the web browser control of ie4 calls this with dwFlags=0
1586 DWORD WINAPI
1587 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1588 INT nMaxExtent, GCP_RESULTSA *lpResults,
1589 DWORD dwFlags)
1591 DWORD ret=0;
1592 SIZE size;
1594 TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1595 debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1597 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1598 "lpOutString=%p lpGlyphs=%p\n",
1599 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1600 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1602 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
1603 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
1604 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1605 if(lpResults->lpClass) FIXME("classes not implemented\n");
1606 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
1608 /* copy will do if the GCP_REORDER flag is not set */
1609 if(lpResults->lpOutString)
1611 lstrcpynA(lpResults->lpOutString, lpString, uCount);
1614 if (lpResults->lpDx)
1616 int i, c;
1617 for (i=0; i<uCount;i++)
1619 if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1620 lpResults->lpDx[i]= c;
1624 if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1625 ret = MAKELONG(size.cx, size.cy);
1627 return ret;
1630 /*************************************************************************
1631 * GetCharacterPlacementW [GDI32.161]
1633 DWORD WINAPI
1634 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1635 INT nMaxExtent, GCP_RESULTSW *lpResults,
1636 DWORD dwFlags)
1638 /* return value 0 is correct for most cases anyway */
1639 FIXME(":stub!\n");
1640 return 0;
1643 /*************************************************************************
1644 * GetCharABCWidthsFloatA [GDI32.150]
1646 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1647 LPABCFLOAT lpABCF)
1649 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1650 return 0;
1653 /*************************************************************************
1654 * GetCharABCWidthsFloatW [GDI32.151]
1656 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1657 UINT iLastChar, LPABCFLOAT lpABCF)
1659 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1660 return 0;
1663 /*************************************************************************
1664 * GetCharWidthFloatA [GDI32.156]
1666 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1667 UINT iLastChar, PFLOAT pxBuffer)
1669 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1670 return 0;
1673 /*************************************************************************
1674 * GetCharWidthFloatW [GDI32.157]
1676 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1677 UINT iLastChar, PFLOAT pxBuffer)
1679 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1680 return 0;