Release 970329
[wine/multimedia.git] / objects / font.c
blob3ac17db2314e49dff2f07e9347b66818ac16ca16
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
6 * Enhacements by Juergen Marquardt 1996
8 * Implementation of a second font cache which
9 * will be updated dynamically
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <X11/Xatom.h>
16 #include "font.h"
17 #include "heap.h"
18 #include "metafile.h"
19 #include "options.h"
20 #include "xmalloc.h"
21 #include "stddebug.h"
22 #include "debug.h"
24 LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
27 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
28 (((cs)->rbearing|(cs)->lbearing| \
29 (cs)->ascent|(cs)->descent) == 0))
31 /*
32 * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
33 * character. If the character is in the column and exists, then return the
34 * appropriate metrics (note that fonts with common per-character metrics will
35 * return min_bounds). If none of these hold true, try again with the default
36 * char.
38 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
39 { \
40 cs = def; \
41 if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
42 if (fs->per_char == NULL) { \
43 cs = &fs->min_bounds; \
44 } else { \
45 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
46 if (CI_NONEXISTCHAR(cs)) cs = def; \
47 } \
48 } \
51 #define CI_GET_DEFAULT_INFO(fs,cs) \
52 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
57 /***********************************************************************
58 * FONT_LOGFONT32AToLOGFONT16
60 static void FONT_LOGFONT32AToLOGFONT16( const LOGFONT32A *font,
61 LPLOGFONT16 font16 )
63 font16->lfHeight = (INT16)font->lfHeight;
64 font16->lfWidth = (INT16)font->lfWidth;
65 font16->lfEscapement = (INT16)font->lfEscapement;
66 font16->lfOrientation = (INT16)font->lfOrientation;
67 font16->lfWeight = (INT16)font->lfWeight;
68 font16->lfItalic = font->lfItalic;
69 font16->lfUnderline = font->lfUnderline;
70 font16->lfStrikeOut = font->lfStrikeOut;
71 font16->lfCharSet = font->lfCharSet;
72 font16->lfOutPrecision = font->lfOutPrecision;
73 font16->lfClipPrecision = font->lfClipPrecision;
74 font16->lfQuality = font->lfQuality;
75 font16->lfPitchAndFamily = font->lfPitchAndFamily;
76 lstrcpyn32A( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
80 /***********************************************************************
81 * FONT_LOGFONT32WToLOGFONT16
83 static void FONT_LOGFONT32WToLOGFONT16( const LOGFONT32W *font,
84 LPLOGFONT16 font16 )
86 font16->lfHeight = (INT16)font->lfHeight;
87 font16->lfWidth = (INT16)font->lfWidth;
88 font16->lfEscapement = (INT16)font->lfEscapement;
89 font16->lfOrientation = (INT16)font->lfOrientation;
90 font16->lfWeight = (INT16)font->lfWeight;
91 font16->lfItalic = font->lfItalic;
92 font16->lfUnderline = font->lfUnderline;
93 font16->lfStrikeOut = font->lfStrikeOut;
94 font16->lfCharSet = font->lfCharSet;
95 font16->lfOutPrecision = font->lfOutPrecision;
96 font16->lfClipPrecision = font->lfClipPrecision;
97 font16->lfQuality = font->lfQuality;
98 font16->lfPitchAndFamily = font->lfPitchAndFamily;
99 lstrcpynWtoA( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
103 /***********************************************************************
104 * FONT_LOGFONT16ToLOGFONT32A
106 static void FONT_LOGFONT16ToLOGFONT32A( LPLOGFONT16 font,
107 LPLOGFONT32A font32A )
109 font32A->lfHeight = (INT32)font->lfHeight;
110 font32A->lfWidth = (INT32)font->lfWidth;
111 font32A->lfEscapement = (INT32)font->lfEscapement;
112 font32A->lfOrientation = (INT32)font->lfOrientation;
113 font32A->lfWeight = (INT32)font->lfWeight;
114 font32A->lfItalic = font->lfItalic;
115 font32A->lfUnderline = font->lfUnderline;
116 font32A->lfStrikeOut = font->lfStrikeOut;
117 font32A->lfCharSet = font->lfCharSet;
118 font32A->lfOutPrecision = font->lfOutPrecision;
119 font32A->lfClipPrecision = font->lfClipPrecision;
120 font32A->lfQuality = font->lfQuality;
121 font32A->lfPitchAndFamily = font->lfPitchAndFamily;
122 lstrcpyn32A( font32A->lfFaceName, font->lfFaceName, LF_FACESIZE );
126 /***********************************************************************
127 * FONT_LOGFONT16ToLOGFONT32W
129 static void FONT_LOGFONT16ToLOGFONT32W( LPLOGFONT16 font,
130 LPLOGFONT32W font32W )
132 font32W->lfHeight = (INT32)font->lfHeight;
133 font32W->lfWidth = (INT32)font->lfWidth;
134 font32W->lfEscapement = (INT32)font->lfEscapement;
135 font32W->lfOrientation = (INT32)font->lfOrientation;
136 font32W->lfWeight = (INT32)font->lfWeight;
137 font32W->lfItalic = font->lfItalic;
138 font32W->lfUnderline = font->lfUnderline;
139 font32W->lfStrikeOut = font->lfStrikeOut;
140 font32W->lfCharSet = font->lfCharSet;
141 font32W->lfOutPrecision = font->lfOutPrecision;
142 font32W->lfClipPrecision = font->lfClipPrecision;
143 font32W->lfQuality = font->lfQuality;
144 font32W->lfPitchAndFamily = font->lfPitchAndFamily;
145 lstrcpynAtoW( font32W->lfFaceName, font->lfFaceName, LF_FACESIZE );
149 /***********************************************************************
150 * FONT_GetMetrics
152 void FONT_GetMetrics( LOGFONT16 * logfont, XFontStruct * xfont,
153 TEXTMETRIC16 * metrics )
155 int average, i, count;
156 unsigned long prop;
158 metrics->tmAscent = xfont->ascent;
159 metrics->tmDescent = xfont->descent;
160 metrics->tmHeight = xfont->ascent + xfont->descent;
162 metrics->tmInternalLeading = 0;
163 if (XGetFontProperty( xfont, XA_CAP_HEIGHT, &prop ))
164 metrics->tmInternalLeading = xfont->ascent+xfont->descent-(INT16)prop;
166 metrics->tmExternalLeading = 0;
167 metrics->tmMaxCharWidth = xfont->max_bounds.width;
168 metrics->tmWeight = logfont->lfWeight;
169 metrics->tmItalic = logfont->lfItalic;
170 metrics->tmUnderlined = logfont->lfUnderline;
171 metrics->tmStruckOut = logfont->lfStrikeOut;
172 metrics->tmFirstChar = xfont->min_char_or_byte2;
173 metrics->tmLastChar = xfont->max_char_or_byte2;
174 metrics->tmDefaultChar = xfont->default_char;
175 metrics->tmBreakChar = ' ';
176 metrics->tmCharSet = logfont->lfCharSet;
177 metrics->tmOverhang = 0;
178 metrics->tmDigitizedAspectX = 1;
179 metrics->tmDigitizedAspectY = 1;
180 metrics->tmPitchAndFamily = (logfont->lfPitchAndFamily&0xf0)|TMPF_DEVICE;
182 /* TMPF_FIXED_PITCH bit means variable pitch...Don't you love Microsoft? */
183 if (xfont->min_bounds.width != xfont->max_bounds.width)
184 metrics->tmPitchAndFamily |= TMPF_FIXED_PITCH;
186 if (!xfont->per_char) average = metrics->tmMaxCharWidth;
187 else
189 XCharStruct * charPtr = xfont->per_char;
190 average = count = 0;
191 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
193 if (!CI_NONEXISTCHAR( charPtr ))
195 average += charPtr->width;
196 count++;
198 charPtr++;
200 if (count) average = (average + count/2) / count;
202 metrics->tmAveCharWidth = average;
206 /***********************************************************************
207 * GetGlyphOutline16 (GDI.309)
209 DWORD GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
210 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
211 LPVOID lpBuffer, const MAT2 *lpmat2 )
213 fprintf( stdnimp,"GetGlyphOutLine16(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
214 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
215 return (DWORD)-1; /* failure */
219 /***********************************************************************
220 * GetGlyphOutline32A (GDI32.186)
222 DWORD GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
223 LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
224 LPVOID lpBuffer, const MAT2 *lpmat2 )
226 fprintf( stdnimp,"GetGlyphOutLine32A(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
227 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
228 return (DWORD)-1; /* failure */
232 /***********************************************************************
233 * GetGlyphOutline32W (GDI32.187)
235 DWORD GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
236 LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
237 LPVOID lpBuffer, const MAT2 *lpmat2 )
239 fprintf( stdnimp,"GetGlyphOutLine32W(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
240 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
241 return (DWORD)-1; /* failure */
245 /***********************************************************************
246 * CreateScalableFontResource16 (GDI.310)
248 BOOL16 CreateScalableFontResource16( UINT16 fHidden, LPCSTR lpszResourceFile,
249 LPCSTR fontFile, LPCSTR path )
251 return CreateScalableFontResource32A( fHidden, lpszResourceFile,
252 fontFile, path );
255 /***********************************************************************
256 * CreateScalableFontResource32A (GDI32.62)
258 BOOL32 CreateScalableFontResource32A( DWORD fHidden, LPCSTR lpszResourceFile,
259 LPCSTR lpszFontFile,
260 LPCSTR lpszCurrentPath )
262 /* fHidden=1 - only visible for the calling app, read-only, not
263 * enumbered with EnumFonts/EnumFontFamilies
264 * lpszCurrentPath can be NULL
266 fprintf(stdnimp,"CreateScalableFontResource(%ld,%s,%s,%s) // empty stub\n",
267 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
268 return FALSE; /* create failed */
272 /***********************************************************************
273 * CreateScalableFontResource32W (GDI32.63)
275 BOOL32 CreateScalableFontResource32W( DWORD fHidden, LPCWSTR lpszResourceFile,
276 LPCWSTR lpszFontFile,
277 LPCWSTR lpszCurrentPath )
279 fprintf(stdnimp,"CreateScalableFontResource32W(%ld,%p,%p,%p) // empty stub\n",
280 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
281 return FALSE; /* create failed */
285 /***********************************************************************
286 * CreateFontIndirect16 (GDI.57)
288 HFONT16 CreateFontIndirect16( const LOGFONT16 *font )
290 FONTOBJ * fontPtr;
291 HFONT16 hfont;
293 if (!font)
295 fprintf(stderr,"CreateFontIndirect: font is NULL : returning NULL\n");
296 return 0;
298 hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
299 if (!hfont) return 0;
300 fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
301 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
302 dprintf_font(stddeb,"CreateFontIndirect(%p (%d,%d)); return %04x\n",
303 font, font->lfHeight, font->lfWidth, hfont);
304 return hfont;
308 /***********************************************************************
309 * CreateFontIndirect32A (GDI32.44)
311 HFONT32 CreateFontIndirect32A( const LOGFONT32A *font )
313 LOGFONT16 font16;
315 FONT_LOGFONT32AToLOGFONT16(font,&font16);
317 return CreateFontIndirect16( &font16 );
321 /***********************************************************************
322 * CreateFontIndirect32W (GDI32.45)
324 HFONT32 CreateFontIndirect32W( const LOGFONT32W *font )
326 LOGFONT16 font16;
328 FONT_LOGFONT32WToLOGFONT16(font,&font16);
329 return CreateFontIndirect16( &font16 );
333 /***********************************************************************
334 * CreateFont16 (GDI.56)
336 HFONT16 CreateFont16( INT16 height, INT16 width, INT16 esc, INT16 orient,
337 INT16 weight, BYTE italic, BYTE underline,
338 BYTE strikeout, BYTE charset, BYTE outpres,
339 BYTE clippres, BYTE quality, BYTE pitch, LPCSTR name )
341 LOGFONT16 logfont = {height, width, esc, orient, weight, italic, underline,
342 strikeout, charset, outpres, clippres, quality, pitch, };
343 dprintf_font(stddeb,"CreateFont16(%d,%d)\n", height, width);
344 if (name) lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
345 else logfont.lfFaceName[0] = '\0';
346 return CreateFontIndirect16( &logfont );
351 /*************************************************************************
352 * CreateFont32A (GDI32.43)
354 HFONT32 CreateFont32A( INT32 height, INT32 width, INT32 esc, INT32 orient,
355 INT32 weight, DWORD italic, DWORD underline,
356 DWORD strikeout, DWORD charset, DWORD outpres,
357 DWORD clippres, DWORD quality, DWORD pitch, LPCSTR name)
359 return (HFONT32)CreateFont16( height, width, esc, orient, weight, italic,
360 underline, strikeout, charset, outpres,
361 clippres, quality, pitch, name );
365 /*************************************************************************
366 * CreateFont32W (GDI32.46)
368 HFONT32 CreateFont32W( INT32 height, INT32 width, INT32 esc, INT32 orient,
369 INT32 weight, DWORD italic, DWORD underline,
370 DWORD strikeout, DWORD charset, DWORD outpres,
371 DWORD clippres, DWORD quality, DWORD pitch,
372 LPCWSTR name )
374 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
375 HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
376 italic, underline, strikeout, charset,
377 outpres, clippres, quality, pitch,
378 namea );
379 HeapFree( GetProcessHeap(), 0, namea );
380 return ret;
384 /***********************************************************************
385 * FONT_GetObject16
387 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
389 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
390 memcpy( buffer, &font->logfont, count );
391 return count;
395 /***********************************************************************
396 * FONT_GetObject32A
398 INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
400 LOGFONT32A fnt32;
402 memset(&fnt32, 0, sizeof(fnt32));
403 fnt32.lfHeight = font->logfont.lfHeight;
404 fnt32.lfWidth = font->logfont.lfWidth;
405 fnt32.lfEscapement = font->logfont.lfEscapement;
406 fnt32.lfOrientation = font->logfont.lfOrientation;
407 fnt32.lfWeight = font->logfont.lfWeight;
408 fnt32.lfItalic = font->logfont.lfItalic;
409 fnt32.lfUnderline = font->logfont.lfUnderline;
410 fnt32.lfStrikeOut = font->logfont.lfStrikeOut;
411 fnt32.lfCharSet = font->logfont.lfCharSet;
412 fnt32.lfOutPrecision = font->logfont.lfOutPrecision;
413 fnt32.lfClipPrecision = font->logfont.lfClipPrecision;
414 fnt32.lfQuality = font->logfont.lfQuality;
415 fnt32.lfPitchAndFamily = font->logfont.lfPitchAndFamily;
416 strncpy( fnt32.lfFaceName, font->logfont.lfFaceName,
417 sizeof(fnt32.lfFaceName) );
419 if (count > sizeof(fnt32)) count = sizeof(fnt32);
420 memcpy( buffer, &fnt32, count );
421 return count;
427 /***********************************************************************
428 * GetTextCharacterExtra16 (GDI.89)
430 INT16 GetTextCharacterExtra16( HDC16 hdc )
432 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
433 if (!dc) return 0;
434 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
435 / dc->vportExtX );
439 /***********************************************************************
440 * GetTextCharacterExtra32 (GDI32.225)
442 INT32 GetTextCharacterExtra32( HDC32 hdc )
444 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
445 if (!dc) return 0;
446 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
447 / dc->vportExtX );
451 /***********************************************************************
452 * SetTextCharacterExtra16 (GDI.8)
454 INT16 SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
456 return (INT16)SetTextCharacterExtra32( hdc, extra );
460 /***********************************************************************
461 * SetTextCharacterExtra32 (GDI32.337)
463 INT32 SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
465 INT32 prev;
466 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
467 if (!dc) return 0;
468 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
469 prev = dc->w.charExtra;
470 dc->w.charExtra = abs(extra);
471 return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
475 /***********************************************************************
476 * SetTextJustification16 (GDI.10)
478 INT16 SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
480 return SetTextJustification32( hdc, extra, breaks );
484 /***********************************************************************
485 * SetTextJustification32 (GDI32.339)
487 BOOL32 SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
489 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
490 if (!dc) return 0;
492 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
493 if (!extra) breaks = 0;
494 dc->w.breakTotalExtra = extra;
495 dc->w.breakCount = breaks;
496 if (breaks)
498 dc->w.breakExtra = extra / breaks;
499 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
501 else
503 dc->w.breakExtra = 0;
504 dc->w.breakRem = 0;
506 return 1;
510 /***********************************************************************
511 * GetTextFace16 (GDI.92)
513 INT16 GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
515 return GetTextFace32A(hdc,count,name);
518 /***********************************************************************
519 * GetTextFace32A (GDI32.234)
521 INT32 GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
523 FONTOBJ *font;
525 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
526 if (!dc) return 0;
527 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
528 return 0;
529 lstrcpyn32A( name, font->logfont.lfFaceName, count );
530 return strlen(name);
533 /***********************************************************************
534 * GetTextFace32W (GDI32.235)
536 INT32 GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
538 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
539 INT32 res = GetTextFace32A(hdc,count,nameA);
540 lstrcpyAtoW( name, nameA );
541 HeapFree( GetProcessHeap(), 0, nameA );
542 return res;
546 /***********************************************************************
547 * GetTextExtent (GDI.91)
549 DWORD GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
551 SIZE16 size;
552 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
553 return MAKELONG( size.cx, size.cy );
557 /***********************************************************************
558 * GetTextExtentPoint16 (GDI.471)
560 * FIXME: Should this have a bug for compatibility?
561 * Original Windows versions of GetTextExtentPoint{A,W} have documented
562 * bugs.
564 BOOL16 GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count, LPSIZE16 size)
566 SIZE32 size32;
567 BOOL32 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
568 CONV_SIZE32TO16( &size32, size );
569 return (BOOL16)ret;
573 /***********************************************************************
574 * GetTextExtentPoint32A (GDI32.230)
576 BOOL32 GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
577 LPSIZE32 size )
579 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
580 if (!dc)
582 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
583 return FALSE;
586 if (!dc->funcs->pGetTextExtentPoint ||
587 !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
588 return FALSE;
590 dprintf_font(stddeb,"GetTextExtentPoint(%08x '%.*s' %d %p): returning %d,%d\n",
591 hdc, count, str, count, size, size->cx, size->cy );
592 return TRUE;
596 /***********************************************************************
597 * GetTextExtentPoint32W (GDI32.231)
599 BOOL32 GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
600 LPSIZE32 size )
602 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
603 BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
604 HeapFree( GetProcessHeap(), 0, p );
605 return ret;
608 /***********************************************************************
609 * GetTextExtentPoint32ABuggy (GDI32.232)
611 BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
612 LPSIZE32 size )
614 dprintf_font( stddeb, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
615 return GetTextExtentPoint32A( hdc, str, count, size );
618 /***********************************************************************
619 * GetTextExtentPoint32WBuggy (GDI32.233)
621 BOOL32 GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
622 LPSIZE32 size )
624 dprintf_font( stddeb, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
625 return GetTextExtentPoint32W( hdc, str, count, size );
629 /***********************************************************************
630 * GetTextExtentExPoint32A (GDI32.228)
632 BOOL32 GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
633 INT32 maxExt,LPINT32 lpnFit, LPINT32 alpDx,
634 LPSIZE32 size )
636 int index;
637 SIZE32 tSize;
638 int nFit=0;
639 int extent=0;
640 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
641 if (!dc)
643 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
644 return FALSE;
646 if (!dc->funcs->pGetTextExtentPoint) return FALSE;
648 size->cx=0; size->cy=0;
649 for(index=0;index<count;index++)
651 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
652 if(extent+tSize.cx<maxExt)
654 extent+=tSize.cx;
655 nFit++;
656 str++;
657 if(alpDx) alpDx[index]=extent;
658 if(tSize.cy > size->cy) size->cy=tSize.cy;
660 else break;
662 size->cx=extent;
663 *lpnFit=nFit;
664 dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
665 hdc,count,str,maxExt,nFit, size->cx,size->cy);
666 return TRUE;
669 /***********************************************************************
670 * GetTextExtentExPoint32W (GDI32.229)
673 BOOL32 GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
674 INT32 maxExt, LPINT32 lpnFit, LPINT32 alpDx,
675 LPSIZE32 size )
677 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
678 BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
679 lpnFit, alpDx, size);
680 HeapFree( GetProcessHeap(), 0, p );
681 return ret;
684 /***********************************************************************
685 * GetTextMetrics16 (GDI.93)
687 BOOL16 GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
689 TEXTMETRIC32A tm;
691 if (!GetTextMetrics32A( (HDC32)hdc, &tm )) return FALSE;
692 metrics->tmHeight = tm.tmHeight;
693 metrics->tmAscent = tm.tmAscent;
694 metrics->tmDescent = tm.tmDescent;
695 metrics->tmInternalLeading = tm.tmInternalLeading;
696 metrics->tmExternalLeading = tm.tmExternalLeading;
697 metrics->tmAveCharWidth = tm.tmAveCharWidth;
698 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
699 metrics->tmWeight = tm.tmWeight;
700 metrics->tmOverhang = tm.tmOverhang;
701 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
702 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
703 metrics->tmFirstChar = tm.tmFirstChar;
704 metrics->tmLastChar = tm.tmLastChar;
705 metrics->tmDefaultChar = tm.tmDefaultChar;
706 metrics->tmBreakChar = tm.tmBreakChar;
707 metrics->tmItalic = tm.tmItalic;
708 metrics->tmUnderlined = tm.tmUnderlined;
709 metrics->tmStruckOut = tm.tmStruckOut;
710 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
711 metrics->tmCharSet = tm.tmCharSet;
712 return TRUE;
716 /***********************************************************************
717 * GetTextMetrics32A (GDI32.236)
719 BOOL32 GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
721 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
722 if (!dc)
724 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
725 return FALSE;
728 if (!dc->funcs->pGetTextMetrics ||
729 !dc->funcs->pGetTextMetrics( dc,metrics ))
730 return FALSE;
731 dprintf_font(stdnimp,"text metrics:\n
732 InternalLeading = %i
733 ExternalLeading = %i
734 MaxCharWidth = %i
735 Weight = %i
736 Italic = %i
737 Underlined = %i
738 StruckOut = %i
739 FirstChar = %i
740 LastChar = %i
741 DefaultChar = %i
742 BreakChar = %i
743 CharSet = %i
744 Overhang = %i
745 DigitizedAspectX = %i
746 DigitizedAspectY = %i
747 AveCharWidth = %i
748 MaxCharWidth = %i
749 Ascent = %i
750 Descent = %i
751 Height = %i\n",
752 metrics->tmInternalLeading,
753 metrics->tmExternalLeading,
754 metrics->tmMaxCharWidth,
755 metrics->tmWeight,
756 metrics->tmItalic,
757 metrics->tmUnderlined,
758 metrics->tmStruckOut,
759 metrics->tmFirstChar,
760 metrics->tmLastChar,
761 metrics->tmDefaultChar,
762 metrics->tmBreakChar,
763 metrics->tmCharSet,
764 metrics->tmOverhang,
765 metrics->tmDigitizedAspectX,
766 metrics->tmDigitizedAspectY,
767 metrics->tmAveCharWidth,
768 metrics->tmMaxCharWidth,
769 metrics->tmAscent,
770 metrics->tmDescent,
771 metrics->tmHeight);
772 return TRUE;
776 /***********************************************************************
777 * GetTextMetrics32W (GDI32.237)
779 BOOL32 GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
781 TEXTMETRIC32A tm;
782 if (!GetTextMetrics32A( (HDC16)hdc, &tm )) return FALSE;
783 metrics->tmHeight = tm.tmHeight;
784 metrics->tmAscent = tm.tmAscent;
785 metrics->tmDescent = tm.tmDescent;
786 metrics->tmInternalLeading = tm.tmInternalLeading;
787 metrics->tmExternalLeading = tm.tmExternalLeading;
788 metrics->tmAveCharWidth = tm.tmAveCharWidth;
789 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
790 metrics->tmWeight = tm.tmWeight;
791 metrics->tmOverhang = tm.tmOverhang;
792 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
793 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
794 metrics->tmFirstChar = tm.tmFirstChar;
795 metrics->tmLastChar = tm.tmLastChar;
796 metrics->tmDefaultChar = tm.tmDefaultChar;
797 metrics->tmBreakChar = tm.tmBreakChar;
798 metrics->tmItalic = tm.tmItalic;
799 metrics->tmUnderlined = tm.tmUnderlined;
800 metrics->tmStruckOut = tm.tmStruckOut;
801 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
802 metrics->tmCharSet = tm.tmCharSet;
803 return TRUE;
807 /***********************************************************************
808 * SetMapperFlags16 (GDI.349)
810 DWORD SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
812 return SetMapperFlags32( hDC, dwFlag );
816 /***********************************************************************
817 * SetMapperFlags32 (GDI32.322)
819 DWORD SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
821 dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
822 hDC, dwFlag);
823 return 0L;
827 /***********************************************************************
828 * GetCharABCWidths16 (GDI.307)
830 BOOL16 GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
831 LPABC16 abc )
833 ABC32 abc32;
834 if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
835 abc->abcA = abc32.abcA;
836 abc->abcB = abc32.abcB;
837 abc->abcC = abc32.abcC;
838 return TRUE;
842 /***********************************************************************
843 * GetCharABCWidths32A (GDI32.149)
845 BOOL32 GetCharABCWidths32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
846 LPABC32 abc )
848 /* No TrueType fonts in Wine so far */
849 fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
850 hdc, firstChar, lastChar, abc );
851 return FALSE;
855 /***********************************************************************
856 * GetCharABCWidths32W (GDI32.152)
858 BOOL32 GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
859 LPABC32 abc )
861 return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
865 /***********************************************************************
866 * GetCharWidth16 (GDI.350)
868 BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
869 LPINT16 buffer )
871 LPINT32 buf32 = (LPINT32)xmalloc(sizeof(INT32)*(1 + (lastChar-firstChar)));
872 LPINT32 obuf32;
873 BOOL32 retVal;
874 int i;
875 if (!buf32)
876 return FALSE;
877 obuf32 = buf32;
878 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
879 if (retVal)
881 for (i = firstChar; i <= lastChar; i++)
883 *buffer++ = *buf32++;
886 free (obuf32);
887 return retVal;
891 /***********************************************************************
892 * GetCharWidth32A (GDI32.155)
894 BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
895 LPINT32 buffer )
897 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
898 if (!dc)
900 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
901 return FALSE;
904 if (!dc->funcs->pGetCharWidth ||
905 !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
906 return FALSE;
908 return TRUE;
912 /***********************************************************************
913 * GetCharWidth32W (GDI32.158)
915 BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
916 LPINT32 buffer )
918 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
922 /***********************************************************************
923 * AddFontResource16 (GDI.119)
925 INT16 AddFontResource16( LPCSTR str )
927 return AddFontResource32A( str );
931 /***********************************************************************
932 * AddFontResource32A (GDI32.2)
934 INT32 AddFontResource32A( LPCSTR str )
936 if (HIWORD(str))
937 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
938 else
939 fprintf( stdnimp, "STUB: AddFontResource(%04x)\n", LOWORD(str) );
940 return 1;
944 /***********************************************************************
945 * AddFontResource32W (GDI32.4)
947 INT32 AddFontResource32W( LPCWSTR str )
949 fprintf( stdnimp, "STUB: AddFontResource32W(%p)\n", str );
950 return 1;
954 /***********************************************************************
955 * RemoveFontResource16 (GDI.136)
957 BOOL16 RemoveFontResource16( LPCSTR str )
959 return RemoveFontResource32A( str );
963 /***********************************************************************
964 * RemoveFontResource32A (GDI32.284)
966 BOOL32 RemoveFontResource32A( LPCSTR str )
968 if (HIWORD(str))
969 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
970 else
971 fprintf( stdnimp, "STUB: RemoveFontResource(%04x)\n", LOWORD(str) );
972 return TRUE;
976 /***********************************************************************
977 * RemoveFontResource32W (GDI32.286)
979 BOOL32 RemoveFontResource32W( LPCWSTR str )
981 fprintf( stdnimp, "STUB: RemoveFontResource32W(%p)\n", str );
982 return TRUE;
986 /*************************************************************************
987 * FONT_ParseFontParms [internal]
989 int FONT_ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
991 int i;
992 if (lpFont == NULL) return 0;
993 if (lpRetStr == NULL) return 0;
994 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
995 if (*lpFont == '-') i++;
996 lpFont++;
998 if (i == wParmsNo) {
999 if (*lpFont == '-') lpFont++;
1000 wMaxSiz--;
1001 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
1002 *(lpRetStr + i) = *lpFont++;
1003 *(lpRetStr + i) = '\0';
1004 return i;
1006 else
1007 lpRetStr[0] = '\0';
1008 return 0;
1013 /*************************************************************************
1014 * InitFontsList [internal]
1017 static int logfcmp(const void *a,const void *b)
1019 return lstrcmpi32A( (*(LPLOGFONT16 *)a)->lfFaceName,
1020 (*(LPLOGFONT16 *)b)->lfFaceName );
1023 void InitFontsList(void)
1025 char str[32];
1026 char pattern[100];
1027 char *family, *weight, *charset;
1028 char **names;
1029 char slant, spacing;
1030 int i, count;
1031 LPLOGFONT16 lpNewFont;
1033 dprintf_font(stddeb,"InitFontsList !\n");
1035 weight = "medium";
1036 slant = 'r';
1037 spacing = '*';
1038 charset = "*";
1039 family = "*-*";
1041 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
1042 family, weight, slant, spacing, charset);
1043 names = XListFonts( display, pattern, MAX_FONTS, &count );
1044 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
1046 lpNewFont = malloc((sizeof(LOGFONT16)+LF_FACESIZE)*count);
1047 if (lpNewFont == NULL) {
1048 dprintf_font(stddeb,
1049 "InitFontsList // Error alloc new font structure !\n");
1050 XFreeFontNames(names);
1051 return;
1054 for (i = 0; i < count; i++) {
1055 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
1057 FONT_ParseFontParms(names[i], 2, str, sizeof(str));
1058 strcpy(lpNewFont->lfFaceName, str);
1059 FONT_ParseFontParms(names[i], 8, str, sizeof(str));
1060 lpNewFont->lfHeight = atoi(str) / 10;
1061 FONT_ParseFontParms(names[i], 12, str, sizeof(str));
1062 lpNewFont->lfWidth = atoi(str) / 10;
1063 lpNewFont->lfEscapement = 0;
1064 lpNewFont->lfOrientation = 0;
1065 lpNewFont->lfWeight = FW_REGULAR;
1066 lpNewFont->lfItalic = 0;
1067 lpNewFont->lfUnderline = 0;
1068 lpNewFont->lfStrikeOut = 0;
1069 FONT_ParseFontParms(names[i], 13, str, sizeof(str));
1070 if (strcmp(str, "iso8859") == 0) {
1071 lpNewFont->lfCharSet = ANSI_CHARSET;
1072 } else {
1073 lpNewFont->lfCharSet = OEM_CHARSET;
1075 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1076 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1077 lpNewFont->lfQuality = DEFAULT_QUALITY;
1078 FONT_ParseFontParms(names[i], 11, str, sizeof(str));
1079 switch(str[0]) {
1080 case 'p':
1081 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
1082 break;
1083 case 'm':
1084 case 'c':
1085 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
1086 break;
1087 default:
1088 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
1089 break;
1091 dprintf_font( stddeb,
1092 "InitFontsList // lpNewFont->lfHeight=%d\n",
1093 lpNewFont->lfHeight );
1094 dprintf_font( stddeb,
1095 "InitFontsList // lpNewFont->lfWidth=%d\n",
1096 lpNewFont->lfWidth );
1097 dprintf_font( stddeb,
1098 "InitFontsList // lfFaceName='%s'\n",
1099 lpNewFont->lfFaceName );
1100 lpLogFontList[i] = lpNewFont;
1101 lpNewFont = (LPLOGFONT16)
1102 ((char *)lpNewFont + sizeof(LOGFONT16)+LF_FACESIZE);
1104 lpLogFontList[i] = NULL;
1106 qsort(lpLogFontList,count,sizeof(*lpLogFontList),logfcmp);
1107 XFreeFontNames(names);
1110 /*************************************************************************
1111 * EnumFonts [GDI.70]
1112 * We reuse EnumFontFamilies* for the callback function get the same
1113 * structs (+ extra stuff at the end which will be ignored by the enum funcs)
1115 INT16 EnumFonts16(HDC16 hDC, LPCSTR lpFaceName, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1117 return EnumFontFamilies16(hDC,lpFaceName,lpEnumFunc,lpData);
1120 /*************************************************************************
1121 * EnumFontsA [GDI32.84]
1123 INT32 EnumFonts32A(HDC32 hDC, LPCSTR lpFaceName, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1125 return EnumFontFamilies32A(hDC,lpFaceName,lpEnumFunc,lpData);
1128 /*************************************************************************
1129 * EnumFontsA [GDI32.84]
1131 INT32 EnumFonts32W(HDC32 hDC, LPCWSTR lpFaceName, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1133 return EnumFontFamilies32W(hDC,lpFaceName,lpEnumFunc,lpData);
1136 /*************************************************************************
1137 * EnumFontFamilies [GDI.330]
1139 INT16 EnumFontFamilies16(HDC16 hDC, LPCSTR lpszFamily, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1141 LOGFONT16 LF;
1143 if (lpszFamily)
1144 strcpy(LF.lfFaceName,lpszFamily);
1145 else
1146 LF.lfFaceName[0]='\0';
1147 LF.lfCharSet = DEFAULT_CHARSET;
1149 return EnumFontFamiliesEx16(hDC,&LF,(FONTENUMPROCEX16)lpEnumFunc,lpData,0);
1152 /*************************************************************************
1153 * EnumFontFamiliesA [GDI32.80]
1155 INT32 EnumFontFamilies32A(HDC32 hDC, LPCSTR lpszFamily, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1157 LOGFONT32A LF;
1159 if (lpszFamily)
1160 strcpy(LF.lfFaceName,lpszFamily);
1161 else
1162 LF.lfFaceName[0]='\0';
1163 LF.lfCharSet = DEFAULT_CHARSET;
1165 return EnumFontFamiliesEx32A(hDC,&LF,(FONTENUMPROCEX32A)lpEnumFunc,lpData,0);
1168 /*************************************************************************
1169 * EnumFontFamiliesW [GDI32.83]
1171 INT32 EnumFontFamilies32W(HDC32 hDC, LPCWSTR lpszFamilyW, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1173 LOGFONT32W LF;
1175 if (lpszFamilyW)
1176 lstrcpy32W(LF.lfFaceName,lpszFamilyW);
1177 else
1178 LF.lfFaceName[0]=0;
1179 LF.lfCharSet = DEFAULT_CHARSET;
1180 return EnumFontFamiliesEx32W(hDC,&LF,(FONTENUMPROCEX32W)lpEnumFunc,lpData,0);
1183 /*************************************************************************
1184 * EnumFontFamiliesEx [GDI.618]
1185 * FIXME: fill the rest of the NEWTEXTMETRICEX and ENUMLOGFONTEX structures.
1186 * (applies to all EnumFontFamiliesEx*)
1187 * winelib/16 support.
1189 INT16 EnumFontFamiliesEx16(HDC16 hDC, LPLOGFONT16 lpLF, FONTENUMPROCEX16 lpEnumFunc, LPARAM lpData,DWORD reserved)
1191 HLOCAL16 hLog;
1192 HLOCAL16 hMet;
1193 HFONT16 hFont;
1194 HFONT16 hOldFont;
1195 LPENUMLOGFONTEX16 lpEnumLogFont;
1196 LPNEWTEXTMETRICEX16 lptm;
1197 LPSTR lpOldName;
1198 char FaceName[LF_FACESIZE];
1199 int nRet = 0;
1200 int i;
1202 dprintf_font(stddeb,"EnumFontFamiliesEx(%04x, '%s', %08lx, %08lx, %08lx)\n",
1203 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData, reserved);
1204 if (lpEnumFunc == 0) return 0;
1205 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX16) );
1206 lpEnumLogFont = (LPENUMLOGFONTEX16) GDI_HEAP_LIN_ADDR(hLog);
1207 if (lpEnumLogFont == NULL) {
1208 fprintf(stderr,"EnumFontFamiliesEx // can't alloc LOGFONT struct !\n");
1209 return 0;
1211 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX16) );
1212 lptm = (LPNEWTEXTMETRICEX16) GDI_HEAP_LIN_ADDR(hMet);
1213 if (lptm == NULL) {
1214 GDI_HEAP_FREE(hLog);
1215 fprintf(stderr,"EnumFontFamiliesEx // can't alloc TEXTMETRIC struct !\n");
1216 return 0;
1218 lpOldName = NULL;
1219 strcpy(FaceName,lpLF->lfFaceName);
1221 if (lpLogFontList[0] == NULL) InitFontsList();
1222 for(i = 0; lpLogFontList[i] != NULL; i++) {
1223 /* lfCharSet */
1224 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1225 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1226 continue;
1228 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1229 /* lfFaceName */
1230 if (FaceName[0])
1232 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1233 continue;
1235 else
1237 if ((lpOldName!=NULL) &&
1238 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1239 continue;
1240 lpOldName=lpLogFontList[i]->lfFaceName;
1243 memcpy(lpEnumLogFont, lpLogFontList[i], sizeof(LOGFONT16));
1244 strcpy(lpEnumLogFont->elfFullName,"");
1245 strcpy(lpEnumLogFont->elfStyle,"");
1246 hFont = CreateFontIndirect16((LPLOGFONT16)lpEnumLogFont);
1247 hOldFont = SelectObject32(hDC, hFont);
1248 GetTextMetrics16(hDC, (LPTEXTMETRIC16)lptm);
1249 SelectObject32(hDC, hOldFont);
1250 DeleteObject32(hFont);
1251 dprintf_font(stddeb, "EnumFontFamiliesEx // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1253 nRet = lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet),
1254 0, lpData );
1255 if (nRet == 0) {
1256 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
1257 break;
1260 GDI_HEAP_FREE(hMet);
1261 GDI_HEAP_FREE(hLog);
1262 return nRet;
1266 /*************************************************************************
1267 * EnumFontFamiliesExA [GDI32.81]
1268 * FIXME: Don't use 16 bit GDI heap functions (applies to EnumFontFamiliesEx32*)
1270 INT32 EnumFontFamiliesEx32A(HDC32 hDC, LPLOGFONT32A lpLF,FONTENUMPROCEX32A lpEnumFunc, LPARAM lpData,DWORD reserved)
1272 HLOCAL16 hLog;
1273 HLOCAL16 hMet;
1274 HFONT32 hFont;
1275 HFONT32 hOldFont;
1276 LPENUMLOGFONTEX32A lpEnumLogFont;
1277 LPNEWTEXTMETRICEX32A lptm;
1278 LPSTR lpOldName;
1279 char FaceName[LF_FACESIZE];
1280 int nRet = 0;
1281 int i;
1283 dprintf_font(stddeb,"EnumFontFamilies32A(%04x, %p, %08lx, %08lx, %08lx)\n",
1284 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData,reserved);
1285 if (lpEnumFunc == 0) return 0;
1286 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32A) );
1287 lpEnumLogFont = (LPENUMLOGFONTEX32A) GDI_HEAP_LIN_ADDR(hLog);
1288 if (lpEnumLogFont == NULL) {
1289 fprintf(stderr,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
1290 return 0;
1292 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32A) );
1293 lptm = (LPNEWTEXTMETRICEX32A) GDI_HEAP_LIN_ADDR(hMet);
1294 if (lptm == NULL) {
1295 GDI_HEAP_FREE(hLog);
1296 fprintf(stderr,"EnumFontFamilies32A // can't alloc TEXTMETRIC struct !\n");
1297 return 0;
1299 lpOldName = NULL;
1300 strcpy(FaceName,lpLF->lfFaceName);
1302 if (lpLogFontList[0] == NULL) InitFontsList();
1303 for(i = 0; lpLogFontList[i] != NULL; i++) {
1304 /* lfCharSet */
1305 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1306 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1307 continue;
1309 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1310 /* lfFaceName */
1311 if (FaceName[0]) {
1312 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1313 continue;
1314 } else {
1315 if ((lpOldName!=NULL) &&
1316 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1317 continue;
1318 lpOldName=lpLogFontList[i]->lfFaceName;
1321 FONT_LOGFONT16ToLOGFONT32A(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1322 strcpy(lpEnumLogFont->elfFullName,"");
1323 strcpy(lpEnumLogFont->elfStyle,"");
1324 strcpy(lpEnumLogFont->elfScript,"");
1325 hFont = CreateFontIndirect32A((LPLOGFONT32A)lpEnumLogFont);
1326 hOldFont = SelectObject32(hDC, hFont);
1327 GetTextMetrics32A(hDC, (LPTEXTMETRIC32A)lptm);
1328 SelectObject32(hDC, hOldFont);
1329 DeleteObject32(hFont);
1330 dprintf_font(stddeb, "EnumFontFamiliesEx32A // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1332 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1333 if (nRet == 0) {
1334 dprintf_font(stddeb,"EnumFontFamiliesEx32A // EnumEnd requested by application !\n");
1335 break;
1338 GDI_HEAP_FREE(hMet);
1339 GDI_HEAP_FREE(hLog);
1340 return nRet;
1344 /*************************************************************************
1345 * EnumFontFamiliesW [GDI32.82]
1347 INT32 EnumFontFamiliesEx32W(HDC32 hDC, LPLOGFONT32W lpLF, FONTENUMPROCEX32W lpEnumFunc, LPARAM lpData, DWORD reserved)
1349 HLOCAL16 hLog;
1350 HLOCAL16 hMet;
1351 HFONT32 hFont;
1352 HFONT32 hOldFont;
1353 LPENUMLOGFONTEX32W lpEnumLogFont;
1354 LPNEWTEXTMETRICEX32W lptm;
1355 LPSTR lpOldName;
1356 int nRet = 0;
1357 int i;
1358 LPSTR lpszFamily;
1360 dprintf_font(stddeb,"EnumFontFamiliesEx32W(%04x, %p, %08lx, %08lx, %08lx)\n",
1361 hDC, lpLF, (DWORD)lpEnumFunc, lpData,reserved);
1362 if (lpEnumFunc == 0) return 0;
1363 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32W) );
1364 lpEnumLogFont = (LPENUMLOGFONTEX32W) GDI_HEAP_LIN_ADDR(hLog);
1365 if (lpEnumLogFont == NULL) {
1366 fprintf(stderr,"EnumFontFamilies32W // can't alloc LOGFONT struct !\n");
1367 return 0;
1369 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32W) );
1370 lptm = (LPNEWTEXTMETRICEX32W) GDI_HEAP_LIN_ADDR(hMet);
1371 if (lptm == NULL) {
1372 GDI_HEAP_FREE(hLog);
1373 fprintf(stderr,"EnumFontFamilies32W // can't alloc TEXTMETRIC struct !\n");
1374 return 0;
1376 lpOldName = NULL;
1377 lpszFamily = HEAP_strdupWtoA( GetProcessHeap(), 0, lpLF->lfFaceName );
1378 if (lpLogFontList[0] == NULL) InitFontsList();
1379 for(i = 0; lpLogFontList[i] != NULL; i++) {
1380 /* lfCharSet */
1381 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1382 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1383 continue;
1385 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1386 /* lfFaceName */
1387 if (lpszFamily[0]) {
1388 if (lstrcmpi32A(lpszFamily,lpLogFontList[i]->lfFaceName))
1389 continue;
1390 } else {
1391 if ((lpOldName!=NULL) &&
1392 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1393 continue;
1394 lpOldName=lpLogFontList[i]->lfFaceName;
1397 FONT_LOGFONT16ToLOGFONT32W(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1398 lpEnumLogFont->elfFullName[0] = 0;
1399 lpEnumLogFont->elfStyle[0] = 0;
1400 lpEnumLogFont->elfScript[0] = 0;
1401 hFont = CreateFontIndirect32W((LPLOGFONT32W)lpEnumLogFont);
1402 hOldFont = SelectObject32(hDC, hFont);
1403 GetTextMetrics32W(hDC, (LPTEXTMETRIC32W)lptm);
1404 SelectObject32(hDC, hOldFont);
1405 DeleteObject32(hFont);
1406 dprintf_font(stddeb, "EnumFontFamilies32W // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1408 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1409 if (nRet == 0) {
1410 dprintf_font(stddeb,"EnumFontFamilies32W // EnumEnd requested by application !\n");
1411 break;
1414 GDI_HEAP_FREE(hMet);
1415 GDI_HEAP_FREE(hLog);
1416 HeapFree( GetProcessHeap(), 0, lpszFamily );
1417 return nRet;
1421 /*************************************************************************
1422 * GetRasterizerCaps16 (GDI.313)
1424 BOOL16 GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes )
1426 return GetRasterizerCaps32( lprs, cbNumBytes );
1430 /*************************************************************************
1431 * GetRasterizerCaps32 (GDI32.216)
1433 BOOL32 GetRasterizerCaps32( LPRASTERIZER_STATUS lprs, UINT32 cbNumBytes )
1435 /* This is not much more than a dummy */
1436 RASTERIZER_STATUS rs;
1438 rs.nSize = sizeof(rs);
1439 rs.wFlags = 0;
1440 rs.nLanguageID = 0;
1441 return TRUE;
1445 /*************************************************************************
1446 * GetKerningPairs16 (GDI.332)
1448 INT16 GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1449 LPKERNINGPAIR16 lpKerningPairs )
1451 /* This has to be dealt with when proper font handling is in place
1453 * At this time kerning is ignored (set to 0)
1455 int i;
1456 fprintf(stdnimp,"GetKerningPairs16: almost empty stub!\n");
1457 for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
1458 return 0;
1462 /*************************************************************************
1463 * GetKerningPairs32A (GDI32.192)
1465 DWORD GetKerningPairs32A( HDC32 hDC, DWORD cPairs,
1466 LPKERNINGPAIR32 lpKerningPairs )
1468 /* This has to be dealt with when proper font handling is in place
1470 * At this time kerning is ignored (set to 0)
1472 int i;
1473 fprintf(stdnimp,"GetKerningPairs32: almost empty stub!\n");
1474 for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
1475 return 0;
1479 /*************************************************************************
1480 * GetKerningPairs32W (GDI32.193)
1482 DWORD GetKerningPairs32W( HDC32 hDC, DWORD cPairs,
1483 LPKERNINGPAIR32 lpKerningPairs )
1485 return GetKerningPairs32A( hDC, cPairs, lpKerningPairs );