Abey George (of Macadamian/Corel)
[wine.git] / objects / font.c
blob03f182758c42221db5550439fb4502e1ec2202cf
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"
18 #include "winnls.h"
20 DEFAULT_DEBUG_CHANNEL(font)
21 DECLARE_DEBUG_CHANNEL(gdi)
23 #define ENUM_UNICODE 0x00000001
25 typedef struct
27 LPLOGFONT16 lpLogFontParam;
28 FONTENUMPROCEX16 lpEnumFunc;
29 LPARAM lpData;
31 LPNEWTEXTMETRICEX16 lpTextMetric;
32 LPENUMLOGFONTEX16 lpLogFont;
33 SEGPTR segTextMetric;
34 SEGPTR segLogFont;
35 } fontEnum16;
37 typedef struct
39 LPLOGFONTW lpLogFontParam;
40 FONTENUMPROCEXW lpEnumFunc;
41 LPARAM lpData;
43 LPNEWTEXTMETRICEXW lpTextMetric;
44 LPENUMLOGFONTEXW lpLogFont;
45 DWORD dwFlags;
46 } fontEnum32;
49 * For TranslateCharsetInfo
51 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
52 #define MAXTCIINDEX 32
53 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
54 /* ANSI */
55 { ANSI_CHARSET, 1252, FS(0)},
56 { EASTEUROPE_CHARSET, 1250, FS(1)},
57 { RUSSIAN_CHARSET, 1251, FS(2)},
58 { GREEK_CHARSET, 1253, FS(3)},
59 { TURKISH_CHARSET, 1254, FS(4)},
60 { HEBREW_CHARSET, 1255, FS(5)},
61 { ARABIC_CHARSET, 1256, FS(6)},
62 { BALTIC_CHARSET, 1257, FS(7)},
63 /* reserved by ANSI */
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 { DEFAULT_CHARSET, 0, FS(0)},
72 /* ANSI and OEM */
73 { THAI_CHARSET, 874, FS(16)},
74 { SHIFTJIS_CHARSET, 932, FS(17)},
75 { GB2312_CHARSET, 936, FS(18)},
76 { HANGEUL_CHARSET, 949, FS(19)},
77 { CHINESEBIG5_CHARSET, 950, FS(20)},
78 { JOHAB_CHARSET, 1361, FS(21)},
79 /* reserved for alternate ANSI and OEM */
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 { DEFAULT_CHARSET, 0, FS(0)},
88 /* reserved for system */
89 { DEFAULT_CHARSET, 0, FS(0)},
90 { DEFAULT_CHARSET, 0, FS(0)},
93 /***********************************************************************
94 * LOGFONT conversion functions.
96 void FONT_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
98 font16->lfHeight = font32->lfHeight;
99 font16->lfWidth = font32->lfWidth;
100 font16->lfEscapement = font32->lfEscapement;
101 font16->lfOrientation = font32->lfOrientation;
102 font16->lfWeight = font32->lfWeight;
103 font16->lfItalic = font32->lfItalic;
104 font16->lfUnderline = font32->lfUnderline;
105 font16->lfStrikeOut = font32->lfStrikeOut;
106 font16->lfCharSet = font32->lfCharSet;
107 font16->lfOutPrecision = font32->lfOutPrecision;
108 font16->lfClipPrecision = font32->lfClipPrecision;
109 font16->lfQuality = font32->lfQuality;
110 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
111 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
114 void FONT_LogFont32WTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
116 font16->lfHeight = font32->lfHeight;
117 font16->lfWidth = font32->lfWidth;
118 font16->lfEscapement = font32->lfEscapement;
119 font16->lfOrientation = font32->lfOrientation;
120 font16->lfWeight = font32->lfWeight;
121 font16->lfItalic = font32->lfItalic;
122 font16->lfUnderline = font32->lfUnderline;
123 font16->lfStrikeOut = font32->lfStrikeOut;
124 font16->lfCharSet = font32->lfCharSet;
125 font16->lfOutPrecision = font32->lfOutPrecision;
126 font16->lfClipPrecision = font32->lfClipPrecision;
127 font16->lfQuality = font32->lfQuality;
128 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
129 lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
132 void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONTA font32 )
134 font32->lfHeight = font16->lfHeight;
135 font32->lfWidth = font16->lfWidth;
136 font32->lfEscapement = font16->lfEscapement;
137 font32->lfOrientation = font16->lfOrientation;
138 font32->lfWeight = font16->lfWeight;
139 font32->lfItalic = font16->lfItalic;
140 font32->lfUnderline = font16->lfUnderline;
141 font32->lfStrikeOut = font16->lfStrikeOut;
142 font32->lfCharSet = font16->lfCharSet;
143 font32->lfOutPrecision = font16->lfOutPrecision;
144 font32->lfClipPrecision = font16->lfClipPrecision;
145 font32->lfQuality = font16->lfQuality;
146 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
147 lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
150 void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONTW font32 )
152 font32->lfHeight = font16->lfHeight;
153 font32->lfWidth = font16->lfWidth;
154 font32->lfEscapement = font16->lfEscapement;
155 font32->lfOrientation = font16->lfOrientation;
156 font32->lfWeight = font16->lfWeight;
157 font32->lfItalic = font16->lfItalic;
158 font32->lfUnderline = font16->lfUnderline;
159 font32->lfStrikeOut = font16->lfStrikeOut;
160 font32->lfCharSet = font16->lfCharSet;
161 font32->lfOutPrecision = font16->lfOutPrecision;
162 font32->lfClipPrecision = font16->lfClipPrecision;
163 font32->lfQuality = font16->lfQuality;
164 font32->lfPitchAndFamily = font16->lfPitchAndFamily;
165 lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
168 void FONT_EnumLogFontEx16To32A( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXA font32 )
170 FONT_LogFont16To32A( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
171 lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
172 lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
173 lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
176 void FONT_EnumLogFontEx16To32W( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXW font32 )
178 FONT_LogFont16To32W( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
179 lstrcpynAtoW( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
180 lstrcpynAtoW( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
181 lstrcpynAtoW( font32->elfScript, font16->elfScript, LF_FACESIZE );
184 /***********************************************************************
185 * TEXTMETRIC conversion functions.
187 void FONT_TextMetric32Ato16(const LPTEXTMETRICA ptm32, LPTEXTMETRIC16 ptm16 )
189 ptm16->tmHeight = ptm32->tmHeight;
190 ptm16->tmAscent = ptm32->tmAscent;
191 ptm16->tmDescent = ptm32->tmDescent;
192 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
193 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
194 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
195 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
196 ptm16->tmWeight = ptm32->tmWeight;
197 ptm16->tmOverhang = ptm32->tmOverhang;
198 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
199 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
200 ptm16->tmFirstChar = ptm32->tmFirstChar;
201 ptm16->tmLastChar = ptm32->tmLastChar;
202 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
203 ptm16->tmBreakChar = ptm32->tmBreakChar;
204 ptm16->tmItalic = ptm32->tmItalic;
205 ptm16->tmUnderlined = ptm32->tmUnderlined;
206 ptm16->tmStruckOut = ptm32->tmStruckOut;
207 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
208 ptm16->tmCharSet = ptm32->tmCharSet;
211 void FONT_TextMetric32Wto16(const LPTEXTMETRICW ptm32, LPTEXTMETRIC16 ptm16 )
213 ptm16->tmHeight = ptm32->tmHeight;
214 ptm16->tmAscent = ptm32->tmAscent;
215 ptm16->tmDescent = ptm32->tmDescent;
216 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
217 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
218 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
219 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
220 ptm16->tmWeight = ptm32->tmWeight;
221 ptm16->tmOverhang = ptm32->tmOverhang;
222 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
223 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
224 ptm16->tmFirstChar = ptm32->tmFirstChar;
225 ptm16->tmLastChar = ptm32->tmLastChar;
226 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
227 ptm16->tmBreakChar = ptm32->tmBreakChar;
228 ptm16->tmItalic = ptm32->tmItalic;
229 ptm16->tmUnderlined = ptm32->tmUnderlined;
230 ptm16->tmStruckOut = ptm32->tmStruckOut;
231 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
232 ptm16->tmCharSet = ptm32->tmCharSet;
235 void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICA ptm32 )
237 ptm32->tmHeight = ptm16->tmHeight;
238 ptm32->tmAscent = ptm16->tmAscent;
239 ptm32->tmDescent = ptm16->tmDescent;
240 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
241 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
242 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
243 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
244 ptm32->tmWeight = ptm16->tmWeight;
245 ptm32->tmOverhang = ptm16->tmOverhang;
246 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
247 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
248 ptm32->tmFirstChar = ptm16->tmFirstChar;
249 ptm32->tmLastChar = ptm16->tmLastChar;
250 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
251 ptm32->tmBreakChar = ptm16->tmBreakChar;
252 ptm32->tmItalic = ptm16->tmItalic;
253 ptm32->tmUnderlined = ptm16->tmUnderlined;
254 ptm32->tmStruckOut = ptm16->tmStruckOut;
255 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
256 ptm32->tmCharSet = ptm16->tmCharSet;
259 void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICW ptm32 )
261 ptm32->tmHeight = ptm16->tmHeight;
262 ptm32->tmAscent = ptm16->tmAscent;
263 ptm32->tmDescent = ptm16->tmDescent;
264 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
265 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
266 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
267 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
268 ptm32->tmWeight = ptm16->tmWeight;
269 ptm32->tmOverhang = ptm16->tmOverhang;
270 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
271 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
272 ptm32->tmFirstChar = ptm16->tmFirstChar;
273 ptm32->tmLastChar = ptm16->tmLastChar;
274 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
275 ptm32->tmBreakChar = ptm16->tmBreakChar;
276 ptm32->tmItalic = ptm16->tmItalic;
277 ptm32->tmUnderlined = ptm16->tmUnderlined;
278 ptm32->tmStruckOut = ptm16->tmStruckOut;
279 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
280 ptm32->tmCharSet = ptm16->tmCharSet;
283 void FONT_TextMetric32Ato32W(const LPTEXTMETRICA ptm32A, LPTEXTMETRICW ptm32W )
285 ptm32W->tmHeight = ptm32A->tmHeight;
286 ptm32W->tmAscent = ptm32A->tmAscent;
287 ptm32W->tmDescent = ptm32A->tmDescent;
288 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
289 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
290 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
291 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
292 ptm32W->tmWeight = ptm32A->tmWeight;
293 ptm32W->tmOverhang = ptm32A->tmOverhang;
294 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
295 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
296 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
297 ptm32W->tmLastChar = ptm32A->tmLastChar;
298 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
299 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
300 ptm32W->tmItalic = ptm32A->tmItalic;
301 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
302 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
303 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
304 ptm32W->tmCharSet = ptm32A->tmCharSet;
307 /***********************************************************************
308 * CreateFontIndirect16 (GDI.57)
310 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
312 HFONT16 hFont = 0;
314 if (font)
316 hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
317 if( hFont )
319 FONTOBJ* fontPtr;
320 fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont );
321 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
323 TRACE("(%i %i %i %i) '%s' %s %s => %04x\n",
324 font->lfHeight, font->lfWidth,
325 font->lfEscapement, font->lfOrientation,
326 font->lfFaceName ? font->lfFaceName : "NULL",
327 font->lfWeight > 400 ? "Bold" : "",
328 font->lfItalic ? "Italic" : "", hFont);
330 if (font->lfEscapement != font->lfOrientation) {
331 /* this should really depend on whether GM_ADVANCED is set */
332 fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
333 WARN("orientation angle %f set to "
334 "escapement angle %f for new font %04x\n",
335 font->lfOrientation/10., font->lfEscapement/10., hFont);
337 GDI_HEAP_UNLOCK( hFont );
340 else WARN("(NULL) => NULL\n");
342 return hFont;
345 /***********************************************************************
346 * CreateFontIndirectA (GDI32.44)
348 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *font )
350 LOGFONT16 font16;
352 FONT_LogFont32ATo16( font, &font16 );
353 return CreateFontIndirect16( &font16 );
356 /***********************************************************************
357 * CreateFontIndirectW (GDI32.45)
359 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *font )
361 LOGFONT16 font16;
363 FONT_LogFont32WTo16( font, &font16 );
364 return CreateFontIndirect16( &font16 );
367 /***********************************************************************
368 * CreateFont16 (GDI.56)
370 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
371 INT16 weight, BYTE italic, BYTE underline,
372 BYTE strikeout, BYTE charset, BYTE outpres,
373 BYTE clippres, BYTE quality, BYTE pitch,
374 LPCSTR name )
376 LOGFONT16 logfont;
378 TRACE("('%s',%d,%d)\n", (name ? name : "(null)") , height, width);
380 logfont.lfHeight = height;
381 logfont.lfWidth = width;
382 logfont.lfEscapement = esc;
383 logfont.lfOrientation = orient;
384 logfont.lfWeight = weight;
385 logfont.lfItalic = italic;
386 logfont.lfUnderline = underline;
387 logfont.lfStrikeOut = strikeout;
388 logfont.lfCharSet = charset;
389 logfont.lfOutPrecision = outpres;
390 logfont.lfClipPrecision = clippres;
391 logfont.lfQuality = quality;
392 logfont.lfPitchAndFamily = pitch;
394 if (name)
395 lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
396 else
397 logfont.lfFaceName[0] = '\0';
399 return CreateFontIndirect16( &logfont );
402 /*************************************************************************
403 * CreateFontA (GDI32.43)
405 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
406 INT orient, INT weight, DWORD italic,
407 DWORD underline, DWORD strikeout, DWORD charset,
408 DWORD outpres, DWORD clippres, DWORD quality,
409 DWORD pitch, LPCSTR name )
411 return (HFONT)CreateFont16( height, width, esc, orient, weight, italic,
412 underline, strikeout, charset, outpres,
413 clippres, quality, pitch, name );
416 /*************************************************************************
417 * CreateFontW (GDI32.46)
419 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
420 INT orient, INT weight, DWORD italic,
421 DWORD underline, DWORD strikeout, DWORD charset,
422 DWORD outpres, DWORD clippres, DWORD quality,
423 DWORD pitch, LPCWSTR name )
425 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
426 HFONT ret = (HFONT)CreateFont16( height, width, esc, orient, weight,
427 italic, underline, strikeout, charset,
428 outpres, clippres, quality, pitch,
429 namea );
430 if (namea) HeapFree( GetProcessHeap(), 0, namea );
431 return ret;
435 /***********************************************************************
436 * FONT_GetObject16
438 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
440 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
441 memcpy( buffer, &font->logfont, count );
442 return count;
445 /***********************************************************************
446 * FONT_GetObjectA
448 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
450 LOGFONTA fnt32;
452 FONT_LogFont16To32A( &font->logfont, &fnt32 );
454 if (count > sizeof(fnt32)) count = sizeof(fnt32);
455 memcpy( buffer, &fnt32, count );
456 return count;
458 /***********************************************************************
459 * FONT_GetObjectW
461 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
463 LOGFONTW fnt32;
465 FONT_LogFont16To32W( &font->logfont, &fnt32 );
467 if (count > sizeof(fnt32)) count = sizeof(fnt32);
468 memcpy( buffer, &fnt32, count );
469 return count;
473 /***********************************************************************
474 * FONT_EnumInstance16
476 * Called by the device driver layer to pass font info
477 * down to the application.
479 static INT FONT_EnumInstance16( LPENUMLOGFONTEX16 plf,
480 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
482 #define pfe ((fontEnum16*)lp)
483 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
484 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
486 memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
487 memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
489 return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
491 #undef pfe
492 return 1;
495 /***********************************************************************
496 * FONT_EnumInstance
498 static INT FONT_EnumInstance( LPENUMLOGFONTEX16 plf,
499 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
501 /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
503 #define pfe ((fontEnum32*)lp)
504 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
505 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
507 /* convert font metrics */
509 if( pfe->dwFlags & ENUM_UNICODE )
511 FONT_EnumLogFontEx16To32W( plf, pfe->lpLogFont );
512 FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICW)(pfe->lpTextMetric) );
514 return pfe->lpEnumFunc( pfe->lpLogFont, pfe->lpTextMetric, fType, pfe->lpData );
516 else
518 ENUMLOGFONTEXA logfont;
520 FONT_EnumLogFontEx16To32A( plf, &logfont);
521 FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICA)pfe->lpTextMetric );
523 return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont,
524 pfe->lpTextMetric, fType, pfe->lpData );
527 #undef pfe
528 return 1;
531 /***********************************************************************
532 * EnumFontFamiliesEx16 (GDI.613)
534 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
535 FONTENUMPROCEX16 efproc, LPARAM lParam,
536 DWORD dwFlags)
538 INT16 retVal = 0;
539 DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
541 if( dc && dc->funcs->pEnumDeviceFonts )
543 LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
544 if( lptm16 )
546 LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
547 if( lplf16 )
549 fontEnum16 fe16;
551 fe16.lpLogFontParam = plf;
552 fe16.lpEnumFunc = efproc;
553 fe16.lpData = lParam;
555 fe16.lpTextMetric = lptm16;
556 fe16.lpLogFont = lplf16;
557 fe16.segTextMetric = SEGPTR_GET(lptm16);
558 fe16.segLogFont = SEGPTR_GET(lplf16);
560 retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
562 SEGPTR_FREE(lplf16);
564 SEGPTR_FREE(lptm16);
567 return retVal;
570 /***********************************************************************
571 * FONT_EnumFontFamiliesEx
573 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc,
574 LPARAM lParam, DWORD dwUnicode)
576 DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
578 if( dc && dc->funcs->pEnumDeviceFonts )
580 LOGFONT16 lf16;
581 NEWTEXTMETRICEXW tm32w;
582 ENUMLOGFONTEXW lf32w;
583 fontEnum32 fe32;
585 fe32.lpLogFontParam = plf;
586 fe32.lpEnumFunc = efproc;
587 fe32.lpData = lParam;
589 fe32.lpTextMetric = &tm32w;
590 fe32.lpLogFont = &lf32w;
591 fe32.dwFlags = dwUnicode;
593 /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
595 if( plf->lfFaceName[0] )
597 if( dwUnicode )
598 lstrcpynWtoA( lf16.lfFaceName, plf->lfFaceName, LF_FACESIZE );
599 else
600 lstrcpynA( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
602 else lf16.lfFaceName[0] = '\0';
603 lf16.lfCharSet = plf->lfCharSet;
605 return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
607 return 0;
610 /***********************************************************************
611 * EnumFontFamiliesExW (GDI32.82)
613 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
614 FONTENUMPROCEXW efproc,
615 LPARAM lParam, DWORD dwFlags )
617 return FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
620 /***********************************************************************
621 * EnumFontFamiliesExA (GDI32.81)
623 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
624 FONTENUMPROCEXA efproc,
625 LPARAM lParam, DWORD dwFlags)
627 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)plf,
628 (FONTENUMPROCEXW)efproc, lParam, 0);
631 /***********************************************************************
632 * EnumFontFamilies16 (GDI.330)
634 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
635 FONTENUMPROC16 efproc, LPARAM lpData )
637 LOGFONT16 lf;
639 lf.lfCharSet = DEFAULT_CHARSET;
640 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
641 else lf.lfFaceName[0] = '\0';
643 return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
646 /***********************************************************************
647 * EnumFontFamiliesA (GDI32.80)
649 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
650 FONTENUMPROCA efproc, LPARAM lpData )
652 LOGFONTA lf;
654 lf.lfCharSet = DEFAULT_CHARSET;
655 if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
656 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
658 return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)&lf,
659 (FONTENUMPROCEXW)efproc, lpData, 0 );
662 /***********************************************************************
663 * EnumFontFamiliesW (GDI32.83)
665 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
666 FONTENUMPROCW efproc, LPARAM lpData )
668 LOGFONTW lf;
670 lf.lfCharSet = DEFAULT_CHARSET;
671 if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
672 else lf.lfFaceName[0] = 0;
674 return FONT_EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROCEXW)efproc,
675 lpData, ENUM_UNICODE );
678 /***********************************************************************
679 * EnumFonts16 (GDI.70)
681 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
682 LPARAM lpData )
684 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
687 /***********************************************************************
688 * EnumFontsA (GDI32.84)
690 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
691 LPARAM lpData )
693 return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
696 /***********************************************************************
697 * EnumFontsW (GDI32.85)
699 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
700 LPARAM lpData )
702 return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
706 /***********************************************************************
707 * GetTextCharacterExtra16 (GDI.89)
709 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
711 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
712 if (!dc) return 0;
713 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
714 / dc->vportExtX );
718 /***********************************************************************
719 * GetTextCharacterExtra (GDI32.225)
721 INT WINAPI GetTextCharacterExtra( HDC hdc )
723 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
724 if (!dc) return 0;
725 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
726 / dc->vportExtX );
730 /***********************************************************************
731 * SetTextCharacterExtra16 (GDI.8)
733 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
735 return (INT16)SetTextCharacterExtra( hdc, extra );
739 /***********************************************************************
740 * SetTextCharacterExtra (GDI32.337)
742 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
744 INT prev;
745 DC * dc = DC_GetDCPtr( hdc );
746 if (!dc) return 0;
747 if (dc->funcs->pSetTextCharacterExtra)
748 return dc->funcs->pSetTextCharacterExtra( dc, extra );
749 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
750 prev = dc->w.charExtra;
751 dc->w.charExtra = abs(extra);
752 return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
756 /***********************************************************************
757 * SetTextJustification16 (GDI.10)
759 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
761 return SetTextJustification( hdc, extra, breaks );
765 /***********************************************************************
766 * SetTextJustification (GDI32.339)
768 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
770 DC * dc = DC_GetDCPtr( hdc );
771 if (!dc) return 0;
772 if (dc->funcs->pSetTextJustification)
773 return dc->funcs->pSetTextJustification( dc, extra, breaks );
775 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
776 if (!extra) breaks = 0;
777 dc->w.breakTotalExtra = extra;
778 dc->w.breakCount = breaks;
779 if (breaks)
781 dc->w.breakExtra = extra / breaks;
782 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
784 else
786 dc->w.breakExtra = 0;
787 dc->w.breakRem = 0;
789 return 1;
793 /***********************************************************************
794 * GetTextFace16 (GDI.92)
796 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
798 return GetTextFaceA(hdc,count,name);
801 /***********************************************************************
802 * GetTextFaceA (GDI32.234)
804 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
806 FONTOBJ *font;
808 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
809 if (!dc) return 0;
810 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
811 return 0;
812 if (name)
813 lstrcpynA( name, font->logfont.lfFaceName, count );
814 GDI_HEAP_UNLOCK( dc->w.hFont );
815 if (name)
816 return strlen(name);
817 else
818 return strlen(font->logfont.lfFaceName) + 1;
821 /***********************************************************************
822 * GetTextFaceW (GDI32.235)
824 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
826 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
827 INT res = GetTextFaceA(hdc,count,nameA);
828 lstrcpyAtoW( name, nameA );
829 HeapFree( GetProcessHeap(), 0, nameA );
830 return res;
834 /***********************************************************************
835 * GetTextExtent16 (GDI.91)
837 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
839 SIZE16 size;
840 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
841 return MAKELONG( size.cx, size.cy );
845 /***********************************************************************
846 * GetTextExtentPoint16 (GDI.471)
848 * FIXME: Should this have a bug for compatibility?
849 * Original Windows versions of GetTextExtentPoint{A,W} have documented
850 * bugs (-> MSDN KB q147647.txt).
852 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
853 LPSIZE16 size )
855 SIZE size32;
856 BOOL ret;
857 TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count,
858 size);
859 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
860 CONV_SIZE32TO16( &size32, size );
861 return (BOOL16)ret;
865 /***********************************************************************
866 * GetTextExtentPoint32A (GDI32.230)
868 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
869 LPSIZE size )
871 LPWSTR p;
872 BOOL ret;
873 UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
874 UINT wlen;
876 /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
877 * We allocate one more than we need so that lstrcpynWtoA can write a
878 * trailing 0 if it wants.
881 wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
882 p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
883 wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
885 ret = GetTextExtentPoint32W( hdc, p, wlen, size );
886 HeapFree( GetProcessHeap(), 0, p );
887 return ret;
891 /***********************************************************************
892 * GetTextExtentPoint32W [GDI32.231] Computes width/height for a string
894 * Computes width and height of the specified string.
896 * RETURNS
897 * Success: TRUE
898 * Failure: FALSE
900 BOOL WINAPI GetTextExtentPoint32W(
901 HDC hdc, /* [in] Handle of device context */
902 LPCWSTR str, /* [in] Address of text string */
903 INT count, /* [in] Number of characters in string */
904 LPSIZE size) /* [out] Address of structure for string size */
906 DC * dc = DC_GetDCPtr( hdc );
907 if (!dc || !dc->funcs->pGetTextExtentPoint ||
908 !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
909 return FALSE;
911 TRACE("(%08x %s %d %p): returning %d,%d\n",
912 hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
913 return TRUE;
917 /***********************************************************************
918 * GetTextExtentPointA (GDI32.232)
920 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
921 LPSIZE size )
923 TRACE("not bug compatible.\n");
924 return GetTextExtentPoint32A( hdc, str, count, size );
927 /***********************************************************************
928 * GetTextExtentPointW (GDI32.233)
930 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
931 LPSIZE size )
933 TRACE("not bug compatible.\n");
934 return GetTextExtentPoint32W( hdc, str, count, size );
938 /***********************************************************************
939 * GetTextExtentExPointA (GDI32.228)
941 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
942 INT maxExt, LPINT lpnFit,
943 LPINT alpDx, LPSIZE size )
945 LPWSTR p;
946 BOOL ret;
948 /* Docs say str should be 0 terminated here, but we'll use count just in case
951 p = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(WCHAR) );
952 lstrcpynAtoW(p, str, count+1);
953 ret = GetTextExtentExPointW( hdc, p, count, maxExt, lpnFit, alpDx, size);
954 HeapFree( GetProcessHeap(), 0, p );
955 return ret;
959 /***********************************************************************
960 * GetTextExtentExPointW (GDI32.229)
963 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
964 INT maxExt, LPINT lpnFit,
965 LPINT alpDx, LPSIZE size )
967 int index, nFit, extent;
968 SIZE tSize;
969 DC * dc = DC_GetDCPtr( hdc );
971 if (!dc || !dc->funcs->pGetTextExtentPoint) return FALSE;
973 size->cx = size->cy = nFit = extent = 0;
974 for(index = 0; index < count; index++)
976 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
977 if( extent+tSize.cx < maxExt )
979 extent+=tSize.cx;
980 nFit++;
981 str++;
982 if( alpDx ) alpDx[index] = extent;
983 if( tSize.cy > size->cy ) size->cy = tSize.cy;
985 else break;
987 size->cx = extent;
988 *lpnFit = nFit;
990 TRACE("(%08x %s %d) returning %d %d %d\n",
991 hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
992 return TRUE;
995 /***********************************************************************
996 * GetTextMetrics16 (GDI.93)
998 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1000 TEXTMETRICA tm32;
1002 if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
1003 FONT_TextMetric32Ato16( &tm32, metrics );
1004 return TRUE;
1008 /***********************************************************************
1009 * GetTextMetricsA (GDI32.236)
1011 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1013 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1014 if (!dc)
1016 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
1017 return FALSE;
1020 if (!dc->funcs->pGetTextMetrics ||
1021 !dc->funcs->pGetTextMetrics( dc, metrics ))
1022 return FALSE;
1024 /* device layer returns values in device units
1025 * therefore we have to convert them to logical */
1027 #define WDPTOLP(x) ((x<0)? \
1028 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
1029 (abs((x)*dc->wndExtX/dc->vportExtX)))
1030 #define HDPTOLP(y) ((y<0)? \
1031 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
1032 (abs((y)*dc->wndExtY/dc->vportExtY)))
1034 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
1035 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
1036 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
1037 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
1038 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
1039 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
1040 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
1041 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
1043 TRACE("text metrics:\n"
1044 " Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1045 " Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1046 " UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1047 " StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1048 " PitchAndFamily = %02x\n"
1049 " --------------------\n"
1050 " InternalLeading = %li\n"
1051 " Ascent = %li\n"
1052 " Descent = %li\n"
1053 " Height = %li\n",
1054 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1055 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1056 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1057 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1058 metrics->tmPitchAndFamily,
1059 metrics->tmInternalLeading,
1060 metrics->tmAscent,
1061 metrics->tmDescent,
1062 metrics->tmHeight );
1063 return TRUE;
1067 /***********************************************************************
1068 * GetTextMetricsW (GDI32.237)
1070 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1072 TEXTMETRICA tm;
1073 if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1074 FONT_TextMetric32Ato32W( &tm, metrics );
1075 return TRUE;
1079 /***********************************************************************
1080 * GetOutlineTextMetrics16 [GDI.308] Gets metrics for TrueType fonts.
1082 * NOTES
1083 * lpOTM should be LPOUTLINETEXTMETRIC
1085 * RETURNS
1086 * Success: Non-zero or size of required buffer
1087 * Failure: 0
1089 UINT16 WINAPI GetOutlineTextMetrics16(
1090 HDC16 hdc, /* [in] Handle of device context */
1091 UINT16 cbData, /* [in] Size of metric data array */
1092 LPOUTLINETEXTMETRIC16 lpOTM) /* [out] Address of metric data array */
1094 FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1095 return 0;
1099 /***********************************************************************
1100 * GetOutlineTextMetricsA [GDI.207] Gets metrics for TrueType fonts.
1103 * RETURNS
1104 * Success: Non-zero or size of required buffer
1105 * Failure: 0
1107 UINT WINAPI GetOutlineTextMetricsA(
1108 HDC hdc, /* [in] Handle of device context */
1109 UINT cbData, /* [in] Size of metric data array */
1110 LPOUTLINETEXTMETRICA lpOTM) /* [out] Address of metric data array */
1114 UINT rtn = FALSE;
1115 LPTEXTMETRICA lptxtMetr;
1119 if (lpOTM == 0)
1122 lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1123 rtn = sizeof(OUTLINETEXTMETRICA);
1124 cbData = rtn;
1125 } else
1127 cbData = sizeof(*lpOTM);
1128 rtn = cbData;
1131 lpOTM->otmSize = cbData;
1133 lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1135 if (!GetTextMetricsA(hdc,lptxtMetr))
1137 return 0;
1138 } else
1140 memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1143 HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1145 lpOTM->otmFilter = 0;
1147 lpOTM->otmPanoseNumber.bFamilyType = 0;
1148 lpOTM->otmPanoseNumber.bSerifStyle = 0;
1149 lpOTM->otmPanoseNumber.bWeight = 0;
1150 lpOTM->otmPanoseNumber.bProportion = 0;
1151 lpOTM->otmPanoseNumber.bContrast = 0;
1152 lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1153 lpOTM->otmPanoseNumber.bArmStyle = 0;
1154 lpOTM->otmPanoseNumber.bLetterform = 0;
1155 lpOTM->otmPanoseNumber.bMidline = 0;
1156 lpOTM->otmPanoseNumber.bXHeight = 0;
1158 lpOTM->otmfsSelection = 0;
1159 lpOTM->otmfsType = 0;
1162 Further fill of the structure not implemented,
1163 Needs real values for the structure members
1166 return rtn;
1169 /***********************************************************************
1170 * GetOutlineTextMetricsW [GDI32.208]
1172 UINT WINAPI GetOutlineTextMetricsW(
1173 HDC hdc, /* [in] Handle of device context */
1174 UINT cbData, /* [in] Size of metric data array */
1175 LPOUTLINETEXTMETRICW lpOTM) /* [out] Address of metric data array */
1177 FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1178 return 0;
1181 /***********************************************************************
1182 * GetCharWidth16 (GDI.350)
1184 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1185 LPINT16 buffer )
1187 BOOL retVal = FALSE;
1189 if( firstChar != lastChar )
1191 LPINT buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1192 sizeof(INT)*(1 + (lastChar - firstChar)));
1193 if( buf32 )
1195 LPINT obuf32 = buf32;
1196 int i;
1198 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1199 if (retVal)
1201 for (i = firstChar; i <= lastChar; i++)
1202 *buffer++ = *buf32++;
1204 HeapFree(GetProcessHeap(), 0, obuf32);
1207 else /* happens quite often to warrant a special treatment */
1209 INT chWidth;
1210 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1211 *buffer = chWidth;
1213 return retVal;
1217 /***********************************************************************
1218 * GetCharWidth32A (GDI32.155)
1220 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1221 LPINT buffer )
1223 UINT i, extra;
1224 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1225 if (!dc)
1227 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
1228 return FALSE;
1231 if (!dc->funcs->pGetCharWidth ||
1232 !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1233 return FALSE;
1235 /* convert device units to logical */
1237 extra = dc->vportExtX >> 1;
1238 for( i = firstChar; i <= lastChar; i++, buffer++ )
1239 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1241 return TRUE;
1245 /***********************************************************************
1246 * GetCharWidth32W (GDI32.158)
1248 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1249 LPINT buffer )
1251 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1255 /* FIXME: all following APIs ******************************************/
1258 /***********************************************************************
1259 * SetMapperFlags16 (GDI.349)
1261 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1263 return SetMapperFlags( hDC, dwFlag );
1267 /***********************************************************************
1268 * SetMapperFlags (GDI32.322)
1270 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1272 DC *dc = DC_GetDCPtr( hDC );
1273 DWORD ret = 0;
1274 if(!dc) return 0;
1275 if(dc->funcs->pSetMapperFlags)
1276 ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1277 else
1278 FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1279 GDI_HEAP_UNLOCK( hDC );
1280 return ret;
1283 /***********************************************************************
1284 * GetAspectRatioFilterEx16 (GDI.486)
1286 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1288 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1289 return FALSE;
1292 /***********************************************************************
1293 * GetAspectRatioFilterEx (GDI32.142)
1295 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1297 FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1298 return FALSE;
1301 /***********************************************************************
1302 * GetCharABCWidths16 (GDI.307)
1304 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1305 LPABC16 abc )
1307 ABC abc32;
1308 if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1309 abc->abcA = abc32.abcA;
1310 abc->abcB = abc32.abcB;
1311 abc->abcC = abc32.abcC;
1312 return TRUE;
1316 /***********************************************************************
1317 * GetCharABCWidthsA (GDI32.149)
1319 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1320 LPABC abc )
1322 return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1326 /******************************************************************************
1327 * GetCharABCWidthsW [GDI32.152] Retrieves widths of characters in range
1329 * PARAMS
1330 * hdc [I] Handle of device context
1331 * firstChar [I] First character in range to query
1332 * lastChar [I] Last character in range to query
1333 * abc [O] Address of character-width structure
1335 * NOTES
1336 * Only works with TrueType fonts
1338 * RETURNS
1339 * Success: TRUE
1340 * Failure: FALSE
1342 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1343 LPABC abc )
1345 /* No TrueType fonts in Wine so far */
1346 FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1347 return FALSE;
1351 /***********************************************************************
1352 * GetGlyphOutline16 (GDI.309)
1354 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1355 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1356 LPVOID lpBuffer, const MAT2 *lpmat2 )
1358 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1359 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1360 return (DWORD)-1; /* failure */
1364 /***********************************************************************
1365 * GetGlyphOutlineA (GDI32.186)
1367 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1368 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1369 LPVOID lpBuffer, const MAT2 *lpmat2 )
1371 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1372 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1373 return (DWORD)-1; /* failure */
1376 /***********************************************************************
1377 * GetGlyphOutlineW (GDI32.187)
1379 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1380 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1381 LPVOID lpBuffer, const MAT2 *lpmat2 )
1383 FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1384 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1385 return (DWORD)-1; /* failure */
1388 /***********************************************************************
1389 * CreateScalableFontResource16 (GDI.310)
1391 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1392 LPCSTR lpszResourceFile,
1393 LPCSTR fontFile, LPCSTR path )
1395 return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1396 fontFile, path );
1399 /***********************************************************************
1400 * CreateScalableFontResourceA (GDI32.62)
1402 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1403 LPCSTR lpszResourceFile,
1404 LPCSTR lpszFontFile,
1405 LPCSTR lpszCurrentPath )
1407 /* fHidden=1 - only visible for the calling app, read-only, not
1408 * enumbered with EnumFonts/EnumFontFamilies
1409 * lpszCurrentPath can be NULL
1411 FIXME("(%ld,%s,%s,%s): stub\n",
1412 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1413 return FALSE; /* create failed */
1416 /***********************************************************************
1417 * CreateScalableFontResourceW (GDI32.63)
1419 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1420 LPCWSTR lpszResourceFile,
1421 LPCWSTR lpszFontFile,
1422 LPCWSTR lpszCurrentPath )
1424 FIXME("(%ld,%p,%p,%p): stub\n",
1425 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1426 return FALSE; /* create failed */
1430 /*************************************************************************
1431 * GetRasterizerCaps16 (GDI.313)
1433 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1435 return GetRasterizerCaps( lprs, cbNumBytes );
1439 /*************************************************************************
1440 * GetRasterizerCaps (GDI32.216)
1442 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1444 lprs->nSize = sizeof(RASTERIZER_STATUS);
1445 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1446 lprs->nLanguageID = 0;
1447 return TRUE;
1451 /*************************************************************************
1452 * GetKerningPairs16 (GDI.332)
1454 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1455 LPKERNINGPAIR16 lpKerningPairs )
1457 /* At this time kerning is ignored (set to 0) */
1458 int i;
1459 FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1460 for (i = 0; i < cPairs; i++)
1461 lpKerningPairs[i].iKernAmount = 0;
1462 return 0;
1467 /*************************************************************************
1468 * GetKerningPairsA (GDI32.192)
1470 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1471 LPKERNINGPAIR lpKerningPairs )
1473 int i;
1474 FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1475 for (i = 0; i < cPairs; i++)
1476 lpKerningPairs[i].iKernAmount = 0;
1477 return 0;
1481 /*************************************************************************
1482 * GetKerningPairsW (GDI32.193)
1484 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1485 LPKERNINGPAIR lpKerningPairs )
1487 return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1490 /*************************************************************************
1491 * TranslateCharsetInfo [GDI32.382]
1493 * Fills a CHARSETINFO structure for a character set, code page, or
1494 * font. This allows making the correspondance between different labelings
1495 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
1496 * of the same encoding.
1498 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1499 * only one codepage should be set in *lpSrc.
1501 * RETURNS
1502 * TRUE on success, FALSE on failure.
1505 BOOL WINAPI TranslateCharsetInfo(
1506 LPDWORD lpSrc, /*
1507 if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1508 if flags == TCI_SRCCHARSET: a character set value
1509 if flags == TCI_SRCCODEPAGE: a code page value
1511 LPCHARSETINFO lpCs, /* structure to receive charset information */
1512 DWORD flags /* determines interpretation of lpSrc */
1514 int index = 0;
1515 switch (flags) {
1516 case TCI_SRCFONTSIG:
1517 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1518 break;
1519 case TCI_SRCCODEPAGE:
1520 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1521 break;
1522 case TCI_SRCCHARSET:
1523 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1524 break;
1525 default:
1526 return FALSE;
1528 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1529 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1530 return TRUE;
1533 /*************************************************************************
1534 * GetFontLanguageInfo (GDI32.182)
1536 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1537 /* return value 0 is correct for most cases anyway */
1538 FIXME("(%x):stub!\n", hdc);
1539 return 0;
1542 /*************************************************************************
1543 * GetFontLanguageInfo (GDI.616)
1545 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1546 /* return value 0 is correct for most cases anyway */
1547 FIXME("(%x):stub!\n",hdc);
1548 return 0;
1551 /*************************************************************************
1552 * GetFontData [GDI32.181] Retrieve data for TrueType font
1554 * RETURNS
1556 * success: Number of bytes returned
1557 * failure: GDI_ERROR
1559 * NOTES
1561 * Calls SetLastError()
1563 * BUGS
1565 * Unimplemented
1567 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
1568 LPVOID buffer, DWORD length)
1570 FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1571 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1572 return GDI_ERROR;
1575 /*************************************************************************
1576 * GetFontData16 [GDI.311]
1579 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1580 LPVOID lpvBuffer, DWORD cbData)
1582 return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1585 /*************************************************************************
1586 * GetCharacterPlacementA [GDI32.160]
1588 * NOTES:
1589 * the web browser control of ie4 calls this with dwFlags=0
1591 DWORD WINAPI
1592 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1593 INT nMaxExtent, GCP_RESULTSA *lpResults,
1594 DWORD dwFlags)
1596 DWORD ret=0;
1597 SIZE size;
1599 TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1600 debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1602 TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1603 "lpOutString=%p lpGlyphs=%p\n",
1604 lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1605 lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1607 if(dwFlags) FIXME("flags 0x%08lx ignored\n", dwFlags);
1608 if(lpResults->lpOrder) FIXME("reordering not implemented\n");
1609 if(lpResults->lpCaretPos) FIXME("caret positions not implemented\n");
1610 if(lpResults->lpClass) FIXME("classes not implemented\n");
1611 if(lpResults->lpGlyphs) FIXME("glyphs not implemented\n");
1613 /* copy will do if the GCP_REORDER flag is not set */
1614 if(lpResults->lpOutString)
1616 lstrcpynA(lpResults->lpOutString, lpString, uCount);
1619 if (lpResults->lpDx)
1621 int i, c;
1622 for (i=0; i<uCount;i++)
1624 if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1625 lpResults->lpDx[i]= c;
1629 if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1630 ret = MAKELONG(size.cx, size.cy);
1632 return ret;
1635 /*************************************************************************
1636 * GetCharacterPlacementW [GDI32.161]
1638 DWORD WINAPI
1639 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1640 INT nMaxExtent, GCP_RESULTSW *lpResults,
1641 DWORD dwFlags)
1643 /* return value 0 is correct for most cases anyway */
1644 FIXME(":stub!\n");
1645 return 0;
1648 /*************************************************************************
1649 * GetCharABCWidthsFloatA [GDI32.150]
1651 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1652 LPABCFLOAT lpABCF)
1654 FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1655 return 0;
1658 /*************************************************************************
1659 * GetCharABCWidthsFloatW [GDI32.151]
1661 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1662 UINT iLastChar, LPABCFLOAT lpABCF)
1664 FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1665 return 0;
1668 /*************************************************************************
1669 * GetCharWidthFloatA [GDI32.156]
1671 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1672 UINT iLastChar, PFLOAT pxBuffer)
1674 FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1675 return 0;
1678 /*************************************************************************
1679 * GetCharWidthFloatW [GDI32.157]
1681 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1682 UINT iLastChar, PFLOAT pxBuffer)
1684 FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1685 return 0;
1689 /***********************************************************************
1691 * Font Resource API *
1693 ***********************************************************************/
1694 /***********************************************************************
1695 * AddFontResource16 (GDI.119)
1697 * Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1699 * FIXME: Load header and find the best-matching font in the fontList;
1700 * fixup dfPoints if all metrics are identical, otherwise create
1701 * new fontAlias. When soft font support is ready this will
1702 * simply create a new fontResource ('filename' will go into
1703 * the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE
1704 * flag set.
1706 INT16 WINAPI AddFontResource16( LPCSTR filename )
1708 return AddFontResourceA( filename );
1712 /***********************************************************************
1713 * AddFontResourceA (GDI32.2)
1715 INT WINAPI AddFontResourceA( LPCSTR str )
1717 FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1718 "this font manually.\n", debugres_a(str));
1719 return 1;
1723 /***********************************************************************
1724 * AddFontResourceW (GDI32.4)
1726 INT WINAPI AddFontResourceW( LPCWSTR str )
1728 FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1729 "this font manually.\n", debugres_w(str));
1730 return 1;
1733 /***********************************************************************
1734 * RemoveFontResource16 (GDI.136)
1736 BOOL16 WINAPI RemoveFontResource16( SEGPTR str )
1738 FIXME("(%s): stub\n", debugres_a(PTR_SEG_TO_LIN(str)));
1739 return TRUE;
1743 /***********************************************************************
1744 * RemoveFontResourceA (GDI32.284)
1746 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1748 /* This is how it should look like */
1750 fontResource** ppfr;
1751 BOOL32 retVal = FALSE;
1753 EnterCriticalSection( &crtsc_fonts_X11 );
1754 for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1755 if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1757 if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1758 (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1760 if( (*ppfr)->fo_count )
1761 (*ppfr)->fr_flags |= FR_REMOVED;
1762 else
1763 XFONT_RemoveFontResource( ppfr );
1765 retVal = TRUE;
1767 LeaveCriticalSection( &crtsc_fonts_X11 );
1768 return retVal;
1770 FIXME("(%s): stub\n", debugres_a(str));
1771 return TRUE;
1775 /***********************************************************************
1776 * RemoveFontResourceW (GDI32.286)
1778 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1780 FIXME("(%s): stub\n", debugres_w(str) );
1781 return TRUE;