source: trunk/src/gdi32/font.cpp@ 10612

Last change on this file since 10612 was 10612, checked in by sandervl, 21 years ago

DT: fixed font creation for ansi_charset

File size: 38.1 KB
Line 
1/* $Id: font.cpp,v 1.37 2004-06-16 10:20:10 sandervl Exp $ */
2
3/*
4 * GDI32 font apis
5 *
6 * Copyright 1999 Edgar Buerkle (Edgar.Buerkle@gmx.ne)
7 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
8 * Copyright 1998 Patrick Haller
9 * Copyright 2003 Innotek Systemberatung GmbH (stauff@innotek.de)
10 *
11 * TODO: EnumFontsA/W, EnumFontFamiliesExA/W not complete
12 *
13 * Parts based on Wine code (991031)
14 *
15 * Copyright 1993 Alexandre Julliard
16 * 1997 Alex Korobka
17 *
18 * Project Odin Software License can be found in LICENSE.TXT
19 *
20 */
21
22/*****************************************************************************
23 * Includes *
24 *****************************************************************************/
25
26#include <odin.h>
27#include <odinwrap.h>
28#include <os2sel.h>
29
30#include <os2win.h>
31#include <stdlib.h>
32#include <stdarg.h>
33#include <ctype.h>
34#include <string.h>
35#include <dbglog.h>
36#include "unicode.h"
37#include <heapstring.h>
38#include <win\options.h>
39#include <wprocess.h>
40#include <odininst.h>
41#include <stats.h>
42#include "oslibgpi.h"
43#include "font.h"
44#include "ft2supp.h"
45
46#define DBG_LOCALLOG DBG_font
47#include "dbglocal.h"
48
49ODINDEBUGCHANNEL(GDI32-FONT)
50
51typedef struct {
52 DWORD userProc;
53 DWORD userData;
54 DWORD dwFlags;
55} ENUMUSERDATA;
56
57/*
58 * For TranslateCharsetInfo
59 */
60#define FS(x) {{0,0,0,0},{0x1<<(x),0}}
61#define MAXTCIINDEX 32
62static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
63 /* ANSI */
64 { ANSI_CHARSET, 1252, FS(0)},
65 { EASTEUROPE_CHARSET, 1250, FS(1)},
66 { RUSSIAN_CHARSET, 1251, FS(2)},
67 { GREEK_CHARSET, 1253, FS(3)},
68 { TURKISH_CHARSET, 1254, FS(4)},
69 { HEBREW_CHARSET, 1255, FS(5)},
70 { ARABIC_CHARSET, 1256, FS(6)},
71 { BALTIC_CHARSET, 1257, FS(7)},
72 /* reserved by ANSI */
73 { DEFAULT_CHARSET, 0, FS(0)},
74 { DEFAULT_CHARSET, 0, FS(0)},
75 { DEFAULT_CHARSET, 0, FS(0)},
76 { DEFAULT_CHARSET, 0, FS(0)},
77 { DEFAULT_CHARSET, 0, FS(0)},
78 { DEFAULT_CHARSET, 0, FS(0)},
79 { DEFAULT_CHARSET, 0, FS(0)},
80 { DEFAULT_CHARSET, 0, FS(0)},
81 /* ANSI and OEM */
82 { THAI_CHARSET, 874, FS(16)},
83 { SHIFTJIS_CHARSET, 932, FS(17)},
84 { GB2312_CHARSET, 936, FS(18)},
85 { HANGEUL_CHARSET, 949, FS(19)},
86 { CHINESEBIG5_CHARSET, 950, FS(20)},
87 { JOHAB_CHARSET, 1361, FS(21)},
88 /* reserved for alternate ANSI and OEM */
89 { DEFAULT_CHARSET, 0, FS(0)},
90 { DEFAULT_CHARSET, 0, FS(0)},
91 { DEFAULT_CHARSET, 0, FS(0)},
92 { DEFAULT_CHARSET, 0, FS(0)},
93 { DEFAULT_CHARSET, 0, FS(0)},
94 { DEFAULT_CHARSET, 0, FS(0)},
95 { DEFAULT_CHARSET, 0, FS(0)},
96 { DEFAULT_CHARSET, 0, FS(0)},
97 /* reserved for system */
98 { DEFAULT_CHARSET, 0, FS(0)},
99 { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
100};
101
102HFONT hFntDefaultGui = NULL;
103
104/*****************************************************************************
105 * Name : static void iFontRename
106 * Purpose : font remapping table to map win32 fonts to OS/2 pendants
107 * Parameters: LPSTR lpstrFaceOriginal - the win32 face name
108 * LPSTR lpstrFaceBuffer - [LF_FACESIZE] buffer to new name
109 * Variables :
110 * Result :
111 * Remark : remapped name is passed back in the buffer
112 * if no mapping pendant is available, return input parameter
113 * as default.
114 * Status :
115 *
116 * Author : Patrick Haller [Fri, 1998/06/12 03:44]
117 *****************************************************************************/
118
119static void iFontRename(LPCSTR lpstrFaceOriginal,
120 LPSTR lpstrFaceTemp)
121{
122 int iRet;
123
124 // NULL is a valid parameter
125 if (lpstrFaceOriginal == NULL)
126 return;
127
128 strncpy(lpstrFaceTemp, lpstrFaceOriginal, LF_FACESIZE);
129 lpstrFaceTemp[LF_FACESIZE-1] = 0;
130
131 {
132 char *y = lpstrFaceTemp;
133 while(*y) {
134 if(IsDBCSLeadByte( *y )) {
135 y += 2; // DBCS skip
136 } else {
137 *y = toupper( *y );
138 y++;
139 }
140 }
141 }
142
143 //lookup table
144 iRet = PROFILE_GetOdinIniString(ODINFONTSECTION,
145 lpstrFaceTemp,
146 lpstrFaceOriginal,
147 lpstrFaceTemp,
148 LF_FACESIZE);
149}
150#ifdef DEBUG
151//******************************************************************************
152//******************************************************************************
153void dprintfLogFont(LOGFONTA *lplf)
154{
155 dprintf(("GDI32: lfHeight = %d\n", lplf->lfHeight));
156 dprintf(("GDI32: lfWidth = %d\n", lplf->lfWidth));
157 dprintf(("GDI32: lfEscapement = %d\n", lplf->lfEscapement));
158 dprintf(("GDI32: lfOrientation = %d\n", lplf->lfOrientation));
159 dprintf(("GDI32: lfWeight = %d\n", lplf->lfWeight));
160 dprintf(("GDI32: lfItalic = %d\n", lplf->lfItalic));
161 dprintf(("GDI32: lfUnderline = %d\n", lplf->lfUnderline));
162 dprintf(("GDI32: lfStrikeOut = %d\n", lplf->lfStrikeOut));
163 dprintf(("GDI32: lfCharSet = %X\n", lplf->lfCharSet));
164 dprintf(("GDI32: lfOutPrecision = %X\n", lplf->lfOutPrecision));
165 dprintf(("GDI32: lfClipPrecision = %X\n", lplf->lfClipPrecision));
166 dprintf(("GDI32: lfQuality = %X\n", lplf->lfQuality));
167 dprintf(("GDI32: lfPitchAndFamily= %X\n", lplf->lfPitchAndFamily));
168 dprintf(("GDI32: lfFaceName = %s\n", lplf->lfFaceName));
169}
170//******************************************************************************
171//******************************************************************************
172void dprintfTextMetrics(TEXTMETRICA *pwtm)
173{
174 dprintf(("pwtm->tmHeight %d", pwtm->tmHeight));
175 dprintf(("pwtm->tmAscent %d", pwtm->tmAscent));
176 dprintf(("pwtm->tmDescent %d", pwtm->tmDescent));
177 dprintf(("pwtm->tmInternalLeading %d", pwtm->tmInternalLeading));
178 dprintf(("pwtm->tmExternalLeading %d", pwtm->tmExternalLeading));
179 dprintf(("pwtm->tmAveCharWidth %d", pwtm->tmAveCharWidth));
180 dprintf(("pwtm->tmMaxCharWidth %d", pwtm->tmMaxCharWidth));
181 dprintf(("pwtm->tmWeight %d", pwtm->tmWeight));
182 dprintf(("pwtm->tmOverhang %d", pwtm->tmOverhang));
183 dprintf(("pwtm->tmDigitizedAspectX %d", pwtm->tmDigitizedAspectX));
184 dprintf(("pwtm->tmDigitizedAspectY %d", pwtm->tmDigitizedAspectY));
185 dprintf(("pwtm->tmFirstChar %d", pwtm->tmFirstChar));
186 dprintf(("pwtm->tmLastChar %d", pwtm->tmLastChar));
187 dprintf(("pwtm->tmDefaultChar %d", pwtm->tmDefaultChar));
188 dprintf(("pwtm->tmBreakChar %d", pwtm->tmBreakChar));
189 dprintf(("pwtm->tmItalic %x", pwtm->tmItalic));
190 dprintf(("pwtm->tmUnderlined %x", pwtm->tmUnderlined));
191 dprintf(("pwtm->tmStruckOut %x", pwtm->tmStruckOut));
192 dprintf(("pwtm->tmPitchAndFamily %x", pwtm->tmPitchAndFamily));
193 dprintf(("pwtm->tmCharSet %x", pwtm->tmCharSet));
194}
195#else
196#define dprintfLogFont(a)
197#define dprintfTextMetrics(a)
198#endif
199//******************************************************************************
200//******************************************************************************
201HFONT WIN32API CreateFontA(int nHeight,
202 int nWidth,
203 int nEscapement,
204 int nOrientation,
205 int fnWeight,
206 DWORD fdwItalic,
207 DWORD fdwUnderline,
208 DWORD fdwStrikeOut,
209 DWORD fdwCharSet,
210 DWORD fdwOutputPrecision,
211 DWORD fdwClipPrecision,
212 DWORD fdwQuality,
213 DWORD fdwPitchAndFamily,
214 LPCSTR lpszFace)
215{
216 CHAR lpstrFaceNew[LF_FACESIZE];
217 HFONT hFont;
218
219 if(lpszFace == NULL)
220 lpszFace = "";
221
222 if(strlen(lpszFace) >= LF_FACESIZE)
223 {
224 dprintf(("ERROR: Invalid string length for font name!!"));
225 SetLastError(ERROR_INVALID_PARAMETER);
226 return 0;
227 }
228
229 iFontRename(lpszFace, lpstrFaceNew);
230
231 dprintf(("lpszFace = %s -> %s\n", lpszFace, lpstrFaceNew));
232
233 LOGFONTA logFont =
234 {
235 nHeight,
236 nWidth,
237 nEscapement,
238 nOrientation,
239 fnWeight,
240 (BYTE)fdwItalic,
241 (BYTE)fdwUnderline,
242 (BYTE)fdwStrikeOut,
243 (BYTE)fdwCharSet,
244 (BYTE)fdwOutputPrecision,
245 (BYTE)fdwClipPrecision,
246 (BYTE)fdwQuality,
247 (BYTE)fdwPitchAndFamily
248 };
249 strcpy(logFont.lfFaceName, lpszFace);
250
251 return CreateFontIndirectA(&logFont);
252}
253//******************************************************************************
254//******************************************************************************
255HFONT WIN32API CreateFontW(int nHeight,
256 int nWidth,
257 int nEscapement,
258 int nOrientation,
259 int fnWeight,
260 DWORD fdwItalic,
261 DWORD fdwUnderline,
262 DWORD fdwStrikeOut,
263 DWORD fdwCharSet,
264 DWORD fdwOutputPrecision,
265 DWORD fdwClipPrecision,
266 DWORD fdwQuality,
267 DWORD fdwPitchAndFamily,
268 LPCWSTR lpszFace)
269{
270 char *astring;
271 HFONT hFont;
272
273 // NULL is valid for lpszFace
274 if(lpszFace != NULL)
275 astring = UnicodeToAsciiString((LPWSTR)lpszFace);
276 else
277 astring = NULL;
278
279 // @@@PH switch to ODIN_ later
280 hFont = CreateFontA(nHeight,
281 nWidth,
282 nEscapement,
283 nOrientation,
284 fnWeight,
285 fdwItalic,
286 fdwUnderline,
287 fdwStrikeOut,
288 fdwCharSet,
289 fdwOutputPrecision,
290 fdwClipPrecision,
291 fdwQuality,
292 fdwPitchAndFamily,
293 astring);
294 if (astring != NULL)
295 FreeAsciiString(astring);
296
297 return(hFont);
298}
299
300//******************************************************************************
301//******************************************************************************
302HFONT WIN32API CreateFontIndirectA(const LOGFONTA* lplf)
303{
304 HFONT hFont;
305 LOGFONTA afont;
306
307 // don't touch user buffer!
308 memcpy(&afont, lplf, sizeof(LOGFONTA));
309 iFontRename(lplf->lfFaceName, afont.lfFaceName);
310
311 dprintf(("lpszFace = (%x) %s -> %s\n", lplf->lfFaceName, lplf->lfFaceName, afont.lfFaceName));
312
313 if( IsDBCSEnv())
314 {
315 if( !strcmp( afont.lfFaceName, "WarpSans" ))
316 {
317 dprintf(("DBCS : WarpSans -> WarpSans Combined"));
318
319 strcpy( afont.lfFaceName, "WarpSans Combined" );
320 }
321
322 }
323 /* TODO: To work around problem in WGSS */
324 if( afont.lfCharSet == ANSI_CHARSET )
325 afont.lfCharSet = DEFAULT_CHARSET;
326
327 dprintf(("GDI32: CreateFontIndirectA\n"));
328 dprintfLogFont((LOGFONTA *)lplf);
329
330 hFont = O32_CreateFontIndirect(&afont);
331 if(hFont) {
332 STATS_CreateFontIndirect(hFont, &afont);
333 RegisterFont(hFont, (LPSTR)lplf->lfFaceName);
334 }
335 return(hFont);
336}
337//******************************************************************************
338//******************************************************************************
339HFONT WIN32API CreateFontIndirectW(const LOGFONTW * lplf)
340{
341 LOGFONTA afont;
342 HFONT hfont;
343
344 //memcpy(&afont, lplf, ((ULONG)&afont.lfFaceName - (ULONG)&afont));
345 memcpy(&afont, lplf, sizeof(LOGFONTA));
346 memset(afont.lfFaceName, 0, LF_FACESIZE);
347 dprintf(("lpszFace = (%x)", lplf->lfFaceName));
348
349 UnicodeToAsciiN((WCHAR *)lplf->lfFaceName, afont.lfFaceName, LF_FACESIZE-1);
350 hfont = CreateFontIndirectA(&afont);
351 return(hfont);
352}
353//******************************************************************************
354//******************************************************************************
355int EXPENTRY_O32 EnumFontProcA(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA
356 lpTextM, DWORD arg3, LPARAM arg4)
357{
358 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
359 FONTENUMPROCA proc = (FONTENUMPROCA)lpEnumData->userProc;
360 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
361
362 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
363 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
364 }
365
366 dprintfLogFont(&lpLogFont->elfLogFont);
367 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
368
369 int rc = proc(lpLogFont, lpTextM, arg3, lpEnumData->userData);
370 SetFS(selTIB); // switch back to the saved FS selector
371 return rc;
372}
373//******************************************************************************
374//******************************************************************************
375int EXPENTRY_O32 EnumFontProcW(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA lpTextM,
376 DWORD arg3, LPARAM arg4)
377{
378 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
379 FONTENUMPROCW proc = (FONTENUMPROCW)lpEnumData->userProc;
380 ENUMLOGFONTW LogFont;
381 NEWTEXTMETRICW textM;
382 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
383 int rc;
384
385 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
386 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
387 }
388
389 dprintfLogFont(&lpLogFont->elfLogFont);
390 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
391
392 memcpy(&LogFont, lpLogFont, ((ULONG)&LogFont.elfLogFont.lfFaceName -
393 (ULONG)&LogFont));
394 AsciiToUnicodeN(lpLogFont->elfLogFont.lfFaceName, LogFont.elfLogFont.lfFaceName, LF_FACESIZE-1);
395 AsciiToUnicodeN((char *) lpLogFont->elfFullName, LogFont.elfFullName, LF_FULLFACESIZE-1);
396 AsciiToUnicodeN((char *) lpLogFont->elfStyle, LogFont.elfStyle, LF_FACESIZE-1);
397
398 textM.tmHeight = lpTextM->tmHeight;
399 textM.tmAscent = lpTextM->tmAscent;
400 textM.tmDescent = lpTextM->tmDescent;
401 textM.tmInternalLeading = lpTextM->tmInternalLeading;
402 textM.tmExternalLeading = lpTextM->tmExternalLeading;
403 textM.tmAveCharWidth = lpTextM->tmAveCharWidth;
404 textM.tmMaxCharWidth = lpTextM->tmMaxCharWidth;
405 textM.tmWeight = lpTextM->tmWeight;
406 textM.tmOverhang = lpTextM->tmOverhang;
407 textM.tmDigitizedAspectX = lpTextM->tmDigitizedAspectX;
408 textM.tmDigitizedAspectY = lpTextM->tmDigitizedAspectY;
409 textM.tmFirstChar = lpTextM->tmFirstChar;
410 textM.tmLastChar = lpTextM->tmLastChar;
411 textM.tmDefaultChar = lpTextM->tmDefaultChar;
412 textM.tmBreakChar = lpTextM->tmBreakChar;
413 textM.tmItalic = lpTextM->tmItalic;
414 textM.tmUnderlined = lpTextM->tmUnderlined;
415 textM.tmStruckOut = lpTextM->tmStruckOut;
416 textM.tmPitchAndFamily = lpTextM->tmPitchAndFamily;
417 textM.tmCharSet = lpTextM->tmCharSet;
418 textM.ntmFlags = 0;
419 textM.ntmSizeEM = 0;
420 textM.ntmCellHeight = 0;
421 textM.ntmAvgWidth = 0;
422
423 rc = proc(&LogFont, &textM, arg3, lpEnumData->userData);
424 SetFS(selTIB); // switch back to the saved FS selector
425 return rc;
426}
427//******************************************************************************
428//TODO: FontEnumdwFlagsEx, script, font signature & NEWTEXTMETRICEX (last part)
429//******************************************************************************
430int EXPENTRY_O32 EnumFontProcExA(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA
431 lpTextM, DWORD FontType, LPARAM arg4)
432{
433 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
434 FONTENUMPROCEXA proc = (FONTENUMPROCEXA)lpEnumData->userProc;
435 ENUMLOGFONTEXA logFont;
436 NEWTEXTMETRICEXA textM;
437 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
438
439 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
440 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
441 }
442
443 dprintfLogFont(&lpLogFont->elfLogFont);
444 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
445
446 memcpy(&logFont, lpLogFont, sizeof(ENUMLOGFONTA));
447 memset(logFont.elfScript, 0, sizeof(logFont.elfScript));
448 memcpy(&textM.ntmTm, lpTextM, sizeof(textM.ntmTm));
449 memset(&textM.ntmFontSig, 0, sizeof(textM.ntmFontSig));
450
451 dprintf(("EnumFontProcExA %s type %x height %d", logFont.elfLogFont.lfFaceName, FontType, textM.ntmTm.tmHeight));
452
453 int rc = proc(&logFont, &textM, FontType, lpEnumData->userData);
454 SetFS(selTIB); // switch back to the saved FS selector
455 return rc;
456}
457//******************************************************************************
458//TODO: FontEnumdwFlagsEx, script, font signature & NEWTEXTMETRICEX (last part)
459//******************************************************************************
460int EXPENTRY_O32 EnumFontProcExW(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA lpTextM,
461 DWORD FontType, LPARAM arg4)
462{
463 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
464 FONTENUMPROCEXW proc = (FONTENUMPROCEXW)lpEnumData->userProc;
465 ENUMLOGFONTEXW LogFont;
466 NEWTEXTMETRICEXW textM;
467 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
468 int rc;
469
470 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
471 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
472 }
473
474 dprintfLogFont(&lpLogFont->elfLogFont);
475 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
476
477 memcpy(&LogFont, lpLogFont, ((ULONG)&LogFont.elfLogFont.lfFaceName - (ULONG)&LogFont));
478 memset(LogFont.elfScript, 0, sizeof(LogFont.elfScript));
479 AsciiToUnicodeN(lpLogFont->elfLogFont.lfFaceName, LogFont.elfLogFont.lfFaceName, LF_FACESIZE-1);
480 AsciiToUnicodeN((char *) lpLogFont->elfFullName, LogFont.elfFullName, LF_FULLFACESIZE-1);
481 AsciiToUnicodeN((char *) lpLogFont->elfStyle, LogFont.elfStyle, LF_FACESIZE-1);
482
483 textM.ntmTm.tmHeight = lpTextM->tmHeight;
484 textM.ntmTm.tmAscent = lpTextM->tmAscent;
485 textM.ntmTm.tmDescent = lpTextM->tmDescent;
486 textM.ntmTm.tmInternalLeading = lpTextM->tmInternalLeading;
487 textM.ntmTm.tmExternalLeading = lpTextM->tmExternalLeading;
488 textM.ntmTm.tmAveCharWidth = lpTextM->tmAveCharWidth;
489 textM.ntmTm.tmMaxCharWidth = lpTextM->tmMaxCharWidth;
490 textM.ntmTm.tmWeight = lpTextM->tmWeight;
491 textM.ntmTm.tmOverhang = lpTextM->tmOverhang;
492 textM.ntmTm.tmDigitizedAspectX = lpTextM->tmDigitizedAspectX;
493 textM.ntmTm.tmDigitizedAspectY = lpTextM->tmDigitizedAspectY;
494 textM.ntmTm.tmFirstChar = lpTextM->tmFirstChar;
495 textM.ntmTm.tmLastChar = lpTextM->tmLastChar;
496 textM.ntmTm.tmDefaultChar = lpTextM->tmDefaultChar;
497 textM.ntmTm.tmBreakChar = lpTextM->tmBreakChar;
498 textM.ntmTm.tmItalic = lpTextM->tmItalic;
499 textM.ntmTm.tmUnderlined = lpTextM->tmUnderlined;
500 textM.ntmTm.tmStruckOut = lpTextM->tmStruckOut;
501 textM.ntmTm.tmPitchAndFamily = lpTextM->tmPitchAndFamily;
502 textM.ntmTm.tmCharSet = lpTextM->tmCharSet;
503 textM.ntmTm.ntmFlags = 0;
504 textM.ntmTm.ntmSizeEM = 0;
505 textM.ntmTm.ntmCellHeight = 0;
506 textM.ntmTm.ntmAvgWidth = 0;
507 memset(&textM.ntmFontSig, 0, sizeof(textM.ntmFontSig));
508
509 dprintf(("EnumFontProcExW %s type %x height %d charset %d/%d", lpLogFont->elfLogFont.lfFaceName, FontType, textM.ntmTm.tmHeight, lpTextM->tmCharSet, lpLogFont->elfLogFont.lfCharSet));
510 rc = proc(&LogFont, &textM, FontType, lpEnumData->userData);
511 SetFS(selTIB); // switch back to the saved FS selector
512 return rc;
513}
514//******************************************************************************
515//******************************************************************************
516int WIN32API EnumFontsA(HDC hdc,
517 LPCSTR arg2,
518 FONTENUMPROCA arg3,
519 LPARAM arg4)
520{
521 //@@@PH shouldn't this rather be O32_EnumFonts ?
522 return EnumFontFamiliesA(hdc, arg2, arg3, arg4);
523}
524//******************************************************************************
525//******************************************************************************
526int WIN32API EnumFontsW(HDC hdc,
527 LPCWSTR arg2,
528 FONTENUMPROCW arg3,
529 LPARAM arg4)
530{
531 //@@@PH shouldn't this rather be O32_EnumFonts ?
532 return EnumFontFamiliesW(hdc, arg2, arg3, arg4);
533}
534//******************************************************************************
535//******************************************************************************
536int WIN32API EnumFontFamiliesA(HDC hdc,
537 LPCSTR lpszFontFamily,
538 FONTENUMPROCA arg3,
539 LPARAM arg4)
540{
541 ENUMUSERDATA enumData;
542 CHAR lpstrFamilyNew[LF_FACESIZE] = "";
543 int rc;
544
545 dprintf(("GDI32: EnumFontFamiliesA %s", lpszFontFamily));
546
547 iFontRename(lpszFontFamily, lpstrFamilyNew);
548
549 enumData.userProc = (DWORD)arg3;
550 enumData.userData = arg4;
551
552 rc = O32_EnumFontFamilies(hdc, lpstrFamilyNew, &EnumFontProcA, (LPARAM)&enumData);
553
554 return rc;
555}
556//******************************************************************************
557//******************************************************************************
558int WIN32API EnumFontFamiliesW(HDC hdc,
559 LPCWSTR lpszFontFamilyW,
560 FONTENUMPROCW arg3,
561 LPARAM arg4)
562{
563 CHAR lpstrFamilyNew[LF_FACESIZE] = "";
564 ENUMUSERDATA enumData;
565 int rc;
566 char *lpszFontFamilyA = UnicodeToAsciiString((LPWSTR)lpszFontFamilyW);
567
568 dprintf(("GDI32: EnumFontFamiliesW %s", lpszFontFamilyA));
569
570 iFontRename(lpszFontFamilyA, lpstrFamilyNew);
571
572 enumData.userProc = (DWORD)arg3;
573 enumData.userData = arg4;
574
575 rc = O32_EnumFontFamilies(hdc, lpstrFamilyNew, &EnumFontProcW, (LPARAM)&enumData);
576
577 if(lpszFontFamilyA) FreeAsciiString(lpszFontFamilyA);
578 return rc;
579}
580//******************************************************************************
581//******************************************************************************
582INT WIN32API EnumFontFamiliesExA(HDC hdc,
583 LPLOGFONTA lpLogFont,
584 FONTENUMPROCEXA arg3,
585 LPARAM arg4,
586 DWORD dwFlags)
587{
588 ENUMUSERDATA enumData;
589 int rc;
590
591 dprintf(("GDI32: EnumFontFamiliesExA not complete %s", lpLogFont->lfFaceName));
592 dprintf(("GDI32: EnumFontFamiliesExA font name %s character set %x", lpLogFont->lfFaceName, lpLogFont->lfCharSet));
593
594 enumData.userProc = (DWORD)arg3;
595 enumData.userData = arg4;
596 enumData.dwFlags = dwFlags;
597
598 rc = O32_EnumFontFamilies(hdc, lpLogFont->lfFaceName, &EnumFontProcExA, (LPARAM)&enumData);
599
600 return rc;
601}
602//******************************************************************************
603//******************************************************************************
604INT WIN32API EnumFontFamiliesExW(HDC hdc,
605 LPLOGFONTW lpLogFont,
606 FONTENUMPROCEXW arg3,
607 LPARAM arg4,
608 DWORD dwFlags)
609{
610 ENUMUSERDATA enumData;
611 int rc;
612 char *astring = UnicodeToAsciiString((LPWSTR)lpLogFont->lfFaceName);
613
614 dprintf(("GDI32: EnumFontFamiliesExW not complete %s", astring));
615 dprintf(("GDI32: EnumFontFamiliesExW font name %s character set %x", astring, lpLogFont->lfCharSet));
616
617 enumData.userProc = (DWORD)arg3;
618 enumData.userData = arg4;
619 enumData.dwFlags = dwFlags;
620
621 rc = O32_EnumFontFamilies(hdc, astring, &EnumFontProcExW, (LPARAM)&enumData);
622
623 FreeAsciiString(astring);
624 return rc;
625}
626
627/*****************************************************************************
628 * Name : DWORD GetFontLanguageInfo
629 * Purpose : The GetFontLanguageInfo function returns information about the
630 * currently selected font for the specified display context.
631 * Applications typically use this information and the
632 * GetCharacterPlacement function to prepare a character string for display.
633 * Parameters: HDC hdc handle to device context
634 * Variables :
635 * Result :
636 * Remark :
637 * Status : UNTESTED STUB
638 *
639 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
640 *****************************************************************************/
641
642DWORD WIN32API GetFontLanguageInfo(HDC hdc)
643{
644 dprintf(("GDI32: GetFontLanguageInfo(%08xh) not implemented.\n",
645 hdc));
646
647 return (0);
648}
649
650
651/*************************************************************************
652 * TranslateCharsetInfo [GDI32.382]
653 *
654 * Fills a CHARSETINFO structure for a character set, code page, or
655 * font. This allows making the correspondance between different labelings
656 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
657 * of the same encoding.
658 *
659 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
660 * only one codepage should be set in *lpSrc.
661 *
662 * RETURNS
663 * TRUE on success, FALSE on failure.
664 *
665 *
666 * LPDWORD lpSrc, if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
667 * if flags == TCI_SRCCHARSET: a character set value
668 * if flags == TCI_SRCCODEPAGE: a code page value
669 * LPCHARSETINFO lpCs, structure to receive charset information
670 * DWORD flags determines interpretation of lpSrc
671 */
672BOOL WIN32API TranslateCharsetInfo(LPDWORD lpSrc, LPCHARSETINFO lpCs,
673 DWORD flags)
674{
675 int index = 0;
676 switch (flags) {
677 case TCI_SRCFONTSIG:
678 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
679 break;
680 case TCI_SRCCODEPAGE:
681 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
682 break;
683 case TCI_SRCCHARSET:
684 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
685 break;
686 default:
687 return FALSE;
688 }
689 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
690 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
691 return TRUE;
692}
693//******************************************************************************
694//******************************************************************************
695BOOL WIN32API GetTextMetricsA( HDC hdc, LPTEXTMETRICA pwtm)
696{
697 BOOL rc;
698
699 rc = O32_GetTextMetrics(hdc, pwtm);
700
701 if(rc == TRUE) {
702 if(FT2Module.Ft2QueryFontType(hdc, NULL) == FT2_FONTTYPE_TRUETYPE) {
703 pwtm->tmPitchAndFamily |= TMPF_TRUETYPE;
704 }
705 }
706 dprintfTextMetrics(pwtm);
707 return(rc);
708}
709//******************************************************************************
710//******************************************************************************
711BOOL WIN32API GetTextMetricsW( HDC hdc, LPTEXTMETRICW pwtm)
712{
713 BOOL rc;
714 TEXTMETRICA atm;
715
716 rc = GetTextMetricsA(hdc, &atm);
717 pwtm->tmHeight = atm.tmHeight;
718 pwtm->tmAscent = atm.tmAscent;
719 pwtm->tmDescent = atm.tmDescent;
720 pwtm->tmInternalLeading = atm.tmInternalLeading;
721 pwtm->tmExternalLeading = atm.tmExternalLeading;
722 pwtm->tmAveCharWidth = atm.tmAveCharWidth;
723 pwtm->tmMaxCharWidth = atm.tmMaxCharWidth;
724 pwtm->tmWeight = atm.tmWeight;
725 pwtm->tmOverhang = atm.tmOverhang;
726 pwtm->tmDigitizedAspectX = atm.tmDigitizedAspectX;
727 pwtm->tmDigitizedAspectY = atm.tmDigitizedAspectY;
728 pwtm->tmFirstChar = atm.tmFirstChar;
729 pwtm->tmLastChar = atm.tmLastChar;
730 pwtm->tmDefaultChar = atm.tmDefaultChar;
731 pwtm->tmBreakChar = atm.tmBreakChar;
732 pwtm->tmItalic = atm.tmItalic;
733 pwtm->tmUnderlined = atm.tmUnderlined;
734 pwtm->tmStruckOut = atm.tmStruckOut;
735 pwtm->tmPitchAndFamily = atm.tmPitchAndFamily;
736 pwtm->tmCharSet = atm.tmCharSet;
737
738 return(rc);
739}
740//******************************************************************************
741//******************************************************************************
742int WIN32API GetTextFaceA( HDC hdc, int nCount, LPSTR lpFaceName)
743{
744 int ret;
745
746 dprintf(("GDI32: GetTextFaceA %x %d %x", hdc, nCount, lpFaceName));
747 ret = O32_GetTextFace(hdc, nCount, lpFaceName);
748 if(ret > 0 && lpFaceName) {
749 dprintf(("GDI32: GetTextFaceA returned %s", lpFaceName));
750 }
751 //We should return the length including null terminator (WGSS doesn't)
752 if(!lpFaceName) ret++;
753
754 return ret;
755}
756//******************************************************************************
757//******************************************************************************
758int WIN32API GetTextFaceW( HDC hdc, int nCount, LPWSTR lpFaceName)
759{
760 char *astring = NULL;
761 int lenA = GetTextFaceA( hdc, 0, NULL );
762 int rc;
763
764 astring = ( char * )malloc( lenA );
765 if( astring == NULL ) //@@VP:2003-11-05 was 'if ( astring )'
766 return 0;
767
768 rc = GetTextFaceA(hdc, lenA, astring);
769
770 if( rc )
771 {
772 if( lpFaceName )
773 {
774 AsciiToUnicodeN(astring, lpFaceName, nCount);
775 rc = lstrlenW( lpFaceName );
776 }
777 else
778 rc = lstrlenAtoW( astring, -1 );
779
780 rc++; // including null-terminator
781 }
782
783 free(astring);
784
785 return rc;
786}
787//******************************************************************************
788//******************************************************************************
789UINT WIN32API GetOutlineTextMetricsA( HDC hdc, UINT arg2, LPOUTLINETEXTMETRICA arg3)
790{
791 dprintf(("GDI32: GetOutlineTextMetricsA %x %x %x", hdc, arg2, arg3));
792 return O32_GetOutlineTextMetrics(hdc, arg2, arg3);
793}
794//******************************************************************************
795//******************************************************************************
796UINT WIN32API GetOutlineTextMetricsW( HDC hdc, UINT arg2, LPOUTLINETEXTMETRICW arg3)
797{
798 dprintf(("!ERROR!: GDI32: GetOutlineTextMetricsW STUB"));
799 // NOTE: This will not work as is (needs UNICODE support)
800// return O32_GetOutlineTextMetrics(hdc, arg2, arg3);
801 return 0;
802}
803/*****************************************************************************
804 * Name : DWORD GetCharacterPlacementA
805 * Purpose : The GetCharacterPlacementA function retrieves information about
806 * a character string, such as character widths, caret positioning,
807 * ordering within the string, and glyph rendering. The type of
808 * information returned depends on the dwFlags parameter and is
809 * based on the currently selected font in the given display context.
810 * The function copies the information to the specified GCP_RESULTSA
811 * structure or to one or more arrays specified by the structure.
812 * Parameters: HDC hdc handle to device context
813 * LPCSTR lpString pointer to string
814 * int nCount number of characters in string
815 * int nMaxExtent maximum extent for displayed string
816 * LPGCP_RESULTSA *lpResults pointer to buffer for placement result
817 * DWORD dwFlags placement flags
818 * Variables :
819 * Result :
820 * Remark :
821 * Status : UNTESTED STUB
822 *
823 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
824 *****************************************************************************/
825
826DWORD WIN32API GetCharacterPlacementA(HDC hdc,
827 LPCSTR lpString,
828 int nCount,
829 int nMaxExtent,
830 GCP_RESULTSA * lpResults,
831 DWORD dwFlags)
832{
833 dprintf(("GDI32: GetCharacterPlacementA(%08xh,%s,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
834 hdc,
835 lpString,
836 nCount,
837 nMaxExtent,
838 lpResults,
839 dwFlags));
840
841 return (0);
842}
843
844/*****************************************************************************
845 * Name : DWORD GetCharacterPlacementW
846 * Purpose : The GetCharacterPlacementW function retrieves information about
847 * a character string, such as character widths, caret positioning,
848 * ordering within the string, and glyph rendering. The type of
849 * information returned depends on the dwFlags parameter and is
850 * based on the currently selected font in the given display context.
851 * The function copies the information to the specified GCP_RESULTSW
852 * structure or to one or more arrays specified by the structure.
853 * Parameters: HDC hdc handle to device context
854 * LPCSTR lpString pointer to string
855 * int nCount number of characters in string
856 * int nMaxExtent maximum extent for displayed string
857 * GCP_RESULTSW *lpResults pointer to buffer for placement result
858 * DWORD dwFlags placement flags
859 * Variables :
860 * Result :
861 * Remark :
862 * Status : Partly working
863 *
864 * Author : Borrowed Rewind Code
865 *****************************************************************************/
866
867DWORD WIN32API GetCharacterPlacementW(HDC hdc,
868 LPCWSTR lpString,
869 int uCount,
870 int nMaxExtent,
871 GCP_RESULTSW *lpResults,
872 DWORD dwFlags)
873{
874 return FT2Module.Ft2GetCharacterPlacementW(hdc, lpString, uCount, nMaxExtent, lpResults, dwFlags);
875}
876
877
878/***********************************************************************
879 * FONT_mbtowc
880 *
881 * Returns a '\0' terminated Unicode translation of str using the
882 * charset of the currently selected font in hdc. If count is -1 then
883 * str is assumed to be '\0' terminated, otherwise it contains the
884 * number of bytes to convert. If plenW is non-NULL, on return it
885 * will point to the number of WCHARs (excluding the '\0') that have
886 * been written. If pCP is non-NULL, on return it will point to the
887 * codepage used in the conversion (NB, this may be CP_SYMBOL so watch
888 * out). The caller should free the returned LPWSTR from the process
889 * heap itself.
890 */
891LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
892{
893 UINT cp = CP_ACP;
894 INT lenW, i;
895 LPWSTR strW;
896 CHARSETINFO csi;
897 int charset = GetTextCharset(hdc);
898
899 if( IsDBCSEnv() && ( charset == 0 ))
900 cp = CP_ACP;
901 else
902 /* Hmm, nicely designed api this one! */
903 if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
904 cp = csi.ciACP;
905 else {
906 switch(charset) {
907 case OEM_CHARSET:
908 cp = GetOEMCP();
909 break;
910 case DEFAULT_CHARSET:
911 cp = GetACP();
912 break;
913
914 case VISCII_CHARSET:
915 case TCVN_CHARSET:
916 case KOI8_CHARSET:
917 case ISO3_CHARSET:
918 case ISO4_CHARSET:
919 /* FIXME: These have no place here, but because x11drv
920 enumerates fonts with these (made up) charsets some apps
921 might use them and then the FIXME below would become
922 annoying. Now we could pick the intended codepage for
923 each of these, but since it's broken anyway we'll just
924 use CP_ACP and hope it'll go away...
925 */
926 cp = CP_ACP;
927 break;
928
929
930 default:
931 dprintf(("Can't find codepage for charset %d\n", charset));
932 break;
933 }
934 }
935
936 dprintf(("cp == %d\n", cp));
937
938 if(count == -1) count = strlen(str);
939 if(cp != CP_SYMBOL) {
940 lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
941 strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
942 MultiByteToWideChar(cp, 0, str, count, strW, lenW);
943 } else {
944 lenW = count;
945 strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
946 for(i = 0; i < count; i++) strW[i] = (BYTE)str[i];
947 }
948 strW[lenW] = '\0';
949 dprintf(("mapped %s -> %ls\n", str, strW));
950 if(plenW) *plenW = lenW;
951 if(pCP) *pCP = cp;
952 return strW;
953}
954
955/*************************************************************************
956 * GetGlyphIndicesA [GDI32.@]
957 */
958DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
959 LPWORD pgi, DWORD flags)
960{
961 DWORD ret;
962 WCHAR *lpstrW;
963 INT countW;
964
965 dprintf(("GDI32: GetGlyphIndicesA (%p, %s, %d, %p, 0x%lx)\n",
966 hdc, lpstr, count, pgi, flags));
967
968 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
969 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
970 HeapFree(GetProcessHeap(), 0, lpstrW);
971
972 return ret;
973}
974
975/*************************************************************************
976 * GetGlyphIndicesW [GDI32.@]
977 */
978DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
979 LPWORD pgi, DWORD flags)
980{
981 DWORD ret;
982
983 dprintf(("GDI32: GetGlyphIndicesW (%ls, %d, %p, 0x%lx)",
984 lpstr, count, pgi, flags));
985
986 if(!hdc) return GDI_ERROR;
987
988 ret = FT2Module.Ft2GetGlyphIndices(hdc, lpstr, count , pgi, flags);
989 if(ret != GDI_ERROR) {
990 for(int i=0;i<ret;i++) {
991 dprintf(("GetGlyphIndices: %c (%x)-> %d", lpstr[i], lpstr[i], pgi[i]));
992 }
993 }
994 return ret;
995}
996
997/***********************************************************************
998 * GetGlyphOutlineA (GDI32.@)
999 */
1000DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1001 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1002 LPVOID lpBuffer, const MAT2 *lpmat2 )
1003{
1004 LPWSTR p = NULL;
1005 DWORD ret;
1006 UINT c;
1007
1008 if ((fuFormat & GGO_GLYPH_INDEX) == 0)
1009 {
1010 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1011 if (p)
1012 {
1013 c = p[0];
1014 }
1015 else
1016 {
1017 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1018 return GDI_ERROR;
1019 }
1020 }
1021 else
1022 {
1023 c = uChar;
1024 }
1025
1026 ret = GetGlyphOutlineW (hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
1027
1028 if (p != NULL)
1029 {
1030 HeapFree (GetProcessHeap(), 0, p);
1031 }
1032
1033 return ret;
1034}
1035
1036/***********************************************************************
1037 * GetGlyphOutlineW (GDI32.@)
1038 */
1039DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1040 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1041 LPVOID lpBuffer, const MAT2 *lpmat2 )
1042{
1043 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
1044
1045 dprintf(("GDI32: GetGlyphOutlineW(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1046 pHps, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 ));
1047
1048 if (!hdc || !pHps)
1049 {
1050 SetLastError(ERROR_INVALID_PARAMETER);
1051 return GDI_ERROR;
1052 }
1053
1054 return FT2Module.Ft2GetGlyphOutline(pHps->hps, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
1055}
1056//******************************************************************************
1057//******************************************************************************
1058DWORD WIN32API GetKerningPairsA( HDC hdc, DWORD nNumPairs, LPKERNINGPAIR lpkrnpair)
1059{
1060 return O32_GetKerningPairs(hdc, nNumPairs, lpkrnpair);
1061}
1062//******************************************************************************
1063//******************************************************************************
Note: See TracBrowser for help on using the repository browser.