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

Last change on this file since 10373 was 10373, checked in by sandervl, 22 years ago

Update

File size: 37.8 KB
Line 
1/* $Id: font.cpp,v 1.35 2004-01-11 11:42:11 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 dprintf(("GDI32: CreateFontIndirectA\n"));
324 dprintfLogFont((LOGFONTA *)lplf);
325
326 hFont = O32_CreateFontIndirect(&afont);
327 if(hFont) {
328 STATS_CreateFontIndirect(hFont, &afont);
329 RegisterFont(hFont, (LPSTR)lplf->lfFaceName);
330 }
331 return(hFont);
332}
333//******************************************************************************
334//******************************************************************************
335HFONT WIN32API CreateFontIndirectW(const LOGFONTW * lplf)
336{
337 LOGFONTA afont;
338 HFONT hfont;
339
340 //memcpy(&afont, lplf, ((ULONG)&afont.lfFaceName - (ULONG)&afont));
341 memcpy(&afont, lplf, sizeof(LOGFONTA));
342 memset(afont.lfFaceName, 0, LF_FACESIZE);
343 dprintf(("lpszFace = (%x)", lplf->lfFaceName));
344
345 UnicodeToAsciiN((WCHAR *)lplf->lfFaceName, afont.lfFaceName, LF_FACESIZE-1);
346 hfont = CreateFontIndirectA(&afont);
347 return(hfont);
348}
349//******************************************************************************
350//******************************************************************************
351int EXPENTRY_O32 EnumFontProcA(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA
352 lpTextM, DWORD arg3, LPARAM arg4)
353{
354 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
355 FONTENUMPROCA proc = (FONTENUMPROCA)lpEnumData->userProc;
356 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
357
358 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
359 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
360 }
361
362 dprintfLogFont(&lpLogFont->elfLogFont);
363 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
364
365 int rc = proc(lpLogFont, lpTextM, arg3, lpEnumData->userData);
366 SetFS(selTIB); // switch back to the saved FS selector
367 return rc;
368}
369//******************************************************************************
370//******************************************************************************
371int EXPENTRY_O32 EnumFontProcW(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA lpTextM,
372 DWORD arg3, LPARAM arg4)
373{
374 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
375 FONTENUMPROCW proc = (FONTENUMPROCW)lpEnumData->userProc;
376 ENUMLOGFONTW LogFont;
377 NEWTEXTMETRICW textM;
378 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
379 int rc;
380
381 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
382 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
383 }
384
385 dprintfLogFont(&lpLogFont->elfLogFont);
386 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
387
388 memcpy(&LogFont, lpLogFont, ((ULONG)&LogFont.elfLogFont.lfFaceName -
389 (ULONG)&LogFont));
390 AsciiToUnicodeN(lpLogFont->elfLogFont.lfFaceName, LogFont.elfLogFont.lfFaceName, LF_FACESIZE-1);
391 AsciiToUnicodeN((char *) lpLogFont->elfFullName, LogFont.elfFullName, LF_FULLFACESIZE-1);
392 AsciiToUnicodeN((char *) lpLogFont->elfStyle, LogFont.elfStyle, LF_FACESIZE-1);
393
394 textM.tmHeight = lpTextM->tmHeight;
395 textM.tmAscent = lpTextM->tmAscent;
396 textM.tmDescent = lpTextM->tmDescent;
397 textM.tmInternalLeading = lpTextM->tmInternalLeading;
398 textM.tmExternalLeading = lpTextM->tmExternalLeading;
399 textM.tmAveCharWidth = lpTextM->tmAveCharWidth;
400 textM.tmMaxCharWidth = lpTextM->tmMaxCharWidth;
401 textM.tmWeight = lpTextM->tmWeight;
402 textM.tmOverhang = lpTextM->tmOverhang;
403 textM.tmDigitizedAspectX = lpTextM->tmDigitizedAspectX;
404 textM.tmDigitizedAspectY = lpTextM->tmDigitizedAspectY;
405 textM.tmFirstChar = lpTextM->tmFirstChar;
406 textM.tmLastChar = lpTextM->tmLastChar;
407 textM.tmDefaultChar = lpTextM->tmDefaultChar;
408 textM.tmBreakChar = lpTextM->tmBreakChar;
409 textM.tmItalic = lpTextM->tmItalic;
410 textM.tmUnderlined = lpTextM->tmUnderlined;
411 textM.tmStruckOut = lpTextM->tmStruckOut;
412 textM.tmPitchAndFamily = lpTextM->tmPitchAndFamily;
413 textM.tmCharSet = lpTextM->tmCharSet;
414 textM.ntmFlags = 0;
415 textM.ntmSizeEM = 0;
416 textM.ntmCellHeight = 0;
417 textM.ntmAvgWidth = 0;
418
419 rc = proc(&LogFont, &textM, arg3, lpEnumData->userData);
420 SetFS(selTIB); // switch back to the saved FS selector
421 return rc;
422}
423//******************************************************************************
424//TODO: FontEnumdwFlagsEx, script, font signature & NEWTEXTMETRICEX (last part)
425//******************************************************************************
426int EXPENTRY_O32 EnumFontProcExA(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA
427 lpTextM, DWORD FontType, LPARAM arg4)
428{
429 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
430 FONTENUMPROCEXA proc = (FONTENUMPROCEXA)lpEnumData->userProc;
431 ENUMLOGFONTEXA logFont;
432 NEWTEXTMETRICEXA textM;
433 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
434
435 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
436 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
437 }
438
439 dprintfLogFont(&lpLogFont->elfLogFont);
440 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
441
442 memcpy(&logFont, lpLogFont, sizeof(ENUMLOGFONTA));
443 memset(logFont.elfScript, 0, sizeof(logFont.elfScript));
444 memcpy(&textM.ntmTm, lpTextM, sizeof(textM.ntmTm));
445 memset(&textM.ntmFontSig, 0, sizeof(textM.ntmFontSig));
446
447 dprintf(("EnumFontProcExA %s type %x height %d", logFont.elfLogFont.lfFaceName, FontType, textM.ntmTm.tmHeight));
448
449 int rc = proc(&logFont, &textM, FontType, lpEnumData->userData);
450 SetFS(selTIB); // switch back to the saved FS selector
451 return rc;
452}
453//******************************************************************************
454//TODO: FontEnumdwFlagsEx, script, font signature & NEWTEXTMETRICEX (last part)
455//******************************************************************************
456int EXPENTRY_O32 EnumFontProcExW(LPENUMLOGFONTA lpLogFont, LPNEWTEXTMETRICA lpTextM,
457 DWORD FontType, LPARAM arg4)
458{
459 ENUMUSERDATA *lpEnumData = (ENUMUSERDATA *)arg4;
460 FONTENUMPROCEXW proc = (FONTENUMPROCEXW)lpEnumData->userProc;
461 ENUMLOGFONTEXW LogFont;
462 NEWTEXTMETRICEXW textM;
463 USHORT selTIB = SetWin32TIB(); // save current FS selector and set win32 sel
464 int rc;
465
466 if(FT2Module.Ft2QueryFontType(0, lpLogFont->elfLogFont.lfFaceName) == FT2_FONTTYPE_TRUETYPE) {
467 lpTextM->tmPitchAndFamily |= TMPF_TRUETYPE;
468 }
469
470 dprintfLogFont(&lpLogFont->elfLogFont);
471 dprintfTextMetrics((TEXTMETRICA *)lpTextM);
472
473 memcpy(&LogFont, lpLogFont, ((ULONG)&LogFont.elfLogFont.lfFaceName - (ULONG)&LogFont));
474 memset(LogFont.elfScript, 0, sizeof(LogFont.elfScript));
475 AsciiToUnicodeN(lpLogFont->elfLogFont.lfFaceName, LogFont.elfLogFont.lfFaceName, LF_FACESIZE-1);
476 AsciiToUnicodeN((char *) lpLogFont->elfFullName, LogFont.elfFullName, LF_FULLFACESIZE-1);
477 AsciiToUnicodeN((char *) lpLogFont->elfStyle, LogFont.elfStyle, LF_FACESIZE-1);
478
479 textM.ntmTm.tmHeight = lpTextM->tmHeight;
480 textM.ntmTm.tmAscent = lpTextM->tmAscent;
481 textM.ntmTm.tmDescent = lpTextM->tmDescent;
482 textM.ntmTm.tmInternalLeading = lpTextM->tmInternalLeading;
483 textM.ntmTm.tmExternalLeading = lpTextM->tmExternalLeading;
484 textM.ntmTm.tmAveCharWidth = lpTextM->tmAveCharWidth;
485 textM.ntmTm.tmMaxCharWidth = lpTextM->tmMaxCharWidth;
486 textM.ntmTm.tmWeight = lpTextM->tmWeight;
487 textM.ntmTm.tmOverhang = lpTextM->tmOverhang;
488 textM.ntmTm.tmDigitizedAspectX = lpTextM->tmDigitizedAspectX;
489 textM.ntmTm.tmDigitizedAspectY = lpTextM->tmDigitizedAspectY;
490 textM.ntmTm.tmFirstChar = lpTextM->tmFirstChar;
491 textM.ntmTm.tmLastChar = lpTextM->tmLastChar;
492 textM.ntmTm.tmDefaultChar = lpTextM->tmDefaultChar;
493 textM.ntmTm.tmBreakChar = lpTextM->tmBreakChar;
494 textM.ntmTm.tmItalic = lpTextM->tmItalic;
495 textM.ntmTm.tmUnderlined = lpTextM->tmUnderlined;
496 textM.ntmTm.tmStruckOut = lpTextM->tmStruckOut;
497 textM.ntmTm.tmPitchAndFamily = lpTextM->tmPitchAndFamily;
498 textM.ntmTm.tmCharSet = lpTextM->tmCharSet;
499 textM.ntmTm.ntmFlags = 0;
500 textM.ntmTm.ntmSizeEM = 0;
501 textM.ntmTm.ntmCellHeight = 0;
502 textM.ntmTm.ntmAvgWidth = 0;
503 memset(&textM.ntmFontSig, 0, sizeof(textM.ntmFontSig));
504
505 dprintf(("EnumFontProcExW %s type %x height %d charset %d/%d", lpLogFont->elfLogFont.lfFaceName, FontType, textM.ntmTm.tmHeight, lpTextM->tmCharSet, lpLogFont->elfLogFont.lfCharSet));
506 rc = proc(&LogFont, &textM, FontType, lpEnumData->userData);
507 SetFS(selTIB); // switch back to the saved FS selector
508 return rc;
509}
510//******************************************************************************
511//******************************************************************************
512int WIN32API EnumFontsA(HDC hdc,
513 LPCSTR arg2,
514 FONTENUMPROCA arg3,
515 LPARAM arg4)
516{
517 //@@@PH shouldn't this rather be O32_EnumFonts ?
518 return EnumFontFamiliesA(hdc, arg2, arg3, arg4);
519}
520//******************************************************************************
521//******************************************************************************
522int WIN32API EnumFontsW(HDC hdc,
523 LPCWSTR arg2,
524 FONTENUMPROCW arg3,
525 LPARAM arg4)
526{
527 //@@@PH shouldn't this rather be O32_EnumFonts ?
528 return EnumFontFamiliesW(hdc, arg2, arg3, arg4);
529}
530//******************************************************************************
531//******************************************************************************
532int WIN32API EnumFontFamiliesA(HDC hdc,
533 LPCSTR lpszFontFamily,
534 FONTENUMPROCA arg3,
535 LPARAM arg4)
536{
537 ENUMUSERDATA enumData;
538 CHAR lpstrFamilyNew[LF_FACESIZE] = "";
539 int rc;
540
541 dprintf(("GDI32: EnumFontFamiliesA %s", lpszFontFamily));
542
543 iFontRename(lpszFontFamily, lpstrFamilyNew);
544
545 enumData.userProc = (DWORD)arg3;
546 enumData.userData = arg4;
547
548 rc = O32_EnumFontFamilies(hdc, lpstrFamilyNew, &EnumFontProcA, (LPARAM)&enumData);
549
550 return rc;
551}
552//******************************************************************************
553//******************************************************************************
554int WIN32API EnumFontFamiliesW(HDC hdc,
555 LPCWSTR lpszFontFamilyW,
556 FONTENUMPROCW arg3,
557 LPARAM arg4)
558{
559 CHAR lpstrFamilyNew[LF_FACESIZE] = "";
560 ENUMUSERDATA enumData;
561 int rc;
562 char *lpszFontFamilyA = UnicodeToAsciiString((LPWSTR)lpszFontFamilyW);
563
564 dprintf(("GDI32: EnumFontFamiliesW %s", lpszFontFamilyA));
565
566 iFontRename(lpszFontFamilyA, lpstrFamilyNew);
567
568 enumData.userProc = (DWORD)arg3;
569 enumData.userData = arg4;
570
571 rc = O32_EnumFontFamilies(hdc, lpstrFamilyNew, &EnumFontProcW, (LPARAM)&enumData);
572
573 if(lpszFontFamilyA) FreeAsciiString(lpszFontFamilyA);
574 return rc;
575}
576//******************************************************************************
577//******************************************************************************
578INT WIN32API EnumFontFamiliesExA(HDC hdc,
579 LPLOGFONTA lpLogFont,
580 FONTENUMPROCEXA arg3,
581 LPARAM arg4,
582 DWORD dwFlags)
583{
584 ENUMUSERDATA enumData;
585 int rc;
586
587 dprintf(("GDI32: EnumFontFamiliesExA not complete %s", lpLogFont->lfFaceName));
588 dprintf(("GDI32: EnumFontFamiliesExA font name %s character set %x", lpLogFont->lfFaceName, lpLogFont->lfCharSet));
589
590 enumData.userProc = (DWORD)arg3;
591 enumData.userData = arg4;
592 enumData.dwFlags = dwFlags;
593
594 rc = O32_EnumFontFamilies(hdc, lpLogFont->lfFaceName, &EnumFontProcExA, (LPARAM)&enumData);
595
596 return rc;
597}
598//******************************************************************************
599//******************************************************************************
600INT WIN32API EnumFontFamiliesExW(HDC hdc,
601 LPLOGFONTW lpLogFont,
602 FONTENUMPROCEXW arg3,
603 LPARAM arg4,
604 DWORD dwFlags)
605{
606 ENUMUSERDATA enumData;
607 int rc;
608 char *astring = UnicodeToAsciiString((LPWSTR)lpLogFont->lfFaceName);
609
610 dprintf(("GDI32: EnumFontFamiliesExW not complete %s", astring));
611 dprintf(("GDI32: EnumFontFamiliesExW font name %s character set %x", astring, lpLogFont->lfCharSet));
612
613 enumData.userProc = (DWORD)arg3;
614 enumData.userData = arg4;
615 enumData.dwFlags = dwFlags;
616
617 rc = O32_EnumFontFamilies(hdc, astring, &EnumFontProcExW, (LPARAM)&enumData);
618
619 FreeAsciiString(astring);
620 return rc;
621}
622
623/*****************************************************************************
624 * Name : DWORD GetFontLanguageInfo
625 * Purpose : The GetFontLanguageInfo function returns information about the
626 * currently selected font for the specified display context.
627 * Applications typically use this information and the
628 * GetCharacterPlacement function to prepare a character string for display.
629 * Parameters: HDC hdc handle to device context
630 * Variables :
631 * Result :
632 * Remark :
633 * Status : UNTESTED STUB
634 *
635 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
636 *****************************************************************************/
637
638DWORD WIN32API GetFontLanguageInfo(HDC hdc)
639{
640 dprintf(("GDI32: GetFontLanguageInfo(%08xh) not implemented.\n",
641 hdc));
642
643 return (0);
644}
645
646
647/*************************************************************************
648 * TranslateCharsetInfo [GDI32.382]
649 *
650 * Fills a CHARSETINFO structure for a character set, code page, or
651 * font. This allows making the correspondance between different labelings
652 * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
653 * of the same encoding.
654 *
655 * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
656 * only one codepage should be set in *lpSrc.
657 *
658 * RETURNS
659 * TRUE on success, FALSE on failure.
660 *
661 *
662 * LPDWORD lpSrc, if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
663 * if flags == TCI_SRCCHARSET: a character set value
664 * if flags == TCI_SRCCODEPAGE: a code page value
665 * LPCHARSETINFO lpCs, structure to receive charset information
666 * DWORD flags determines interpretation of lpSrc
667 */
668BOOL WIN32API TranslateCharsetInfo(LPDWORD lpSrc, LPCHARSETINFO lpCs,
669 DWORD flags)
670{
671 int index = 0;
672 switch (flags) {
673 case TCI_SRCFONTSIG:
674 while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
675 break;
676 case TCI_SRCCODEPAGE:
677 while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
678 break;
679 case TCI_SRCCHARSET:
680 while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
681 break;
682 default:
683 return FALSE;
684 }
685 if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
686 memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
687 return TRUE;
688}
689//******************************************************************************
690//******************************************************************************
691BOOL WIN32API GetTextMetricsA( HDC hdc, LPTEXTMETRICA pwtm)
692{
693 BOOL rc;
694
695 rc = O32_GetTextMetrics(hdc, pwtm);
696
697 if(rc == TRUE) {
698 if(FT2Module.Ft2QueryFontType(hdc, NULL) == FT2_FONTTYPE_TRUETYPE) {
699 pwtm->tmPitchAndFamily |= TMPF_TRUETYPE;
700 }
701 }
702 dprintfTextMetrics(pwtm);
703 return(rc);
704}
705//******************************************************************************
706//******************************************************************************
707BOOL WIN32API GetTextMetricsW( HDC hdc, LPTEXTMETRICW pwtm)
708{
709 BOOL rc;
710 TEXTMETRICA atm;
711
712 rc = GetTextMetricsA(hdc, &atm);
713 pwtm->tmHeight = atm.tmHeight;
714 pwtm->tmAscent = atm.tmAscent;
715 pwtm->tmDescent = atm.tmDescent;
716 pwtm->tmInternalLeading = atm.tmInternalLeading;
717 pwtm->tmExternalLeading = atm.tmExternalLeading;
718 pwtm->tmAveCharWidth = atm.tmAveCharWidth;
719 pwtm->tmMaxCharWidth = atm.tmMaxCharWidth;
720 pwtm->tmWeight = atm.tmWeight;
721 pwtm->tmOverhang = atm.tmOverhang;
722 pwtm->tmDigitizedAspectX = atm.tmDigitizedAspectX;
723 pwtm->tmDigitizedAspectY = atm.tmDigitizedAspectY;
724 pwtm->tmFirstChar = atm.tmFirstChar;
725 pwtm->tmLastChar = atm.tmLastChar;
726 pwtm->tmDefaultChar = atm.tmDefaultChar;
727 pwtm->tmBreakChar = atm.tmBreakChar;
728 pwtm->tmItalic = atm.tmItalic;
729 pwtm->tmUnderlined = atm.tmUnderlined;
730 pwtm->tmStruckOut = atm.tmStruckOut;
731 pwtm->tmPitchAndFamily = atm.tmPitchAndFamily;
732 pwtm->tmCharSet = atm.tmCharSet;
733
734 return(rc);
735}
736//******************************************************************************
737//******************************************************************************
738int WIN32API GetTextFaceA( HDC hdc, int nCount, LPSTR lpFaceName)
739{
740 int ret;
741
742 dprintf(("GDI32: GetTextFaceA %x %d %x", hdc, nCount, lpFaceName));
743 ret = O32_GetTextFace(hdc, nCount, lpFaceName);
744 if(ret > 0 && lpFaceName) {
745 dprintf(("GDI32: GetTextFaceA returned %s", lpFaceName));
746 }
747 //We should return the length including null terminator (WGSS doesn't)
748 if(!lpFaceName) ret++;
749
750 return ret;
751}
752//******************************************************************************
753//******************************************************************************
754int WIN32API GetTextFaceW( HDC hdc, int nCount, LPWSTR lpFaceName)
755{
756 char *astring = NULL;
757 int lenA = GetTextFaceA( hdc, 0, NULL );
758 int rc;
759
760 astring = ( char * )malloc( lenA );
761 if( astring == NULL ) //@@VP:2003-11-05 was 'if ( astring )'
762 return 0;
763
764 rc = GetTextFaceA(hdc, lenA, astring);
765
766 if( rc )
767 {
768 if( lpFaceName )
769 {
770 AsciiToUnicodeN(astring, lpFaceName, nCount);
771 rc = lstrlenW( lpFaceName );
772 }
773 else
774 rc = lstrlenAtoW( astring, -1 );
775
776 rc++; // including null-terminator
777 }
778
779 free(astring);
780
781 return rc;
782}
783//******************************************************************************
784//******************************************************************************
785UINT WIN32API GetOutlineTextMetricsA( HDC hdc, UINT arg2, LPOUTLINETEXTMETRICA arg3)
786{
787 dprintf(("GDI32: GetOutlineTextMetricsA %x %x %x", hdc, arg2, arg3));
788 return O32_GetOutlineTextMetrics(hdc, arg2, arg3);
789}
790//******************************************************************************
791//******************************************************************************
792UINT WIN32API GetOutlineTextMetricsW( HDC hdc, UINT arg2, LPOUTLINETEXTMETRICW arg3)
793{
794 dprintf(("!ERROR!: GDI32: GetOutlineTextMetricsW STUB"));
795 // NOTE: This will not work as is (needs UNICODE support)
796// return O32_GetOutlineTextMetrics(hdc, arg2, arg3);
797 return 0;
798}
799/*****************************************************************************
800 * Name : DWORD GetCharacterPlacementA
801 * Purpose : The GetCharacterPlacementA function retrieves information about
802 * a character string, such as character widths, caret positioning,
803 * ordering within the string, and glyph rendering. The type of
804 * information returned depends on the dwFlags parameter and is
805 * based on the currently selected font in the given display context.
806 * The function copies the information to the specified GCP_RESULTSA
807 * structure or to one or more arrays specified by the structure.
808 * Parameters: HDC hdc handle to device context
809 * LPCSTR lpString pointer to string
810 * int nCount number of characters in string
811 * int nMaxExtent maximum extent for displayed string
812 * LPGCP_RESULTSA *lpResults pointer to buffer for placement result
813 * DWORD dwFlags placement flags
814 * Variables :
815 * Result :
816 * Remark :
817 * Status : UNTESTED STUB
818 *
819 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
820 *****************************************************************************/
821
822DWORD WIN32API GetCharacterPlacementA(HDC hdc,
823 LPCSTR lpString,
824 int nCount,
825 int nMaxExtent,
826 GCP_RESULTSA * lpResults,
827 DWORD dwFlags)
828{
829 dprintf(("GDI32: GetCharacterPlacementA(%08xh,%s,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
830 hdc,
831 lpString,
832 nCount,
833 nMaxExtent,
834 lpResults,
835 dwFlags));
836
837 return (0);
838}
839
840/*****************************************************************************
841 * Name : DWORD GetCharacterPlacementW
842 * Purpose : The GetCharacterPlacementW function retrieves information about
843 * a character string, such as character widths, caret positioning,
844 * ordering within the string, and glyph rendering. The type of
845 * information returned depends on the dwFlags parameter and is
846 * based on the currently selected font in the given display context.
847 * The function copies the information to the specified GCP_RESULTSW
848 * structure or to one or more arrays specified by the structure.
849 * Parameters: HDC hdc handle to device context
850 * LPCSTR lpString pointer to string
851 * int nCount number of characters in string
852 * int nMaxExtent maximum extent for displayed string
853 * GCP_RESULTSW *lpResults pointer to buffer for placement result
854 * DWORD dwFlags placement flags
855 * Variables :
856 * Result :
857 * Remark :
858 * Status : Partly working
859 *
860 * Author : Borrowed Rewind Code
861 *****************************************************************************/
862
863DWORD WIN32API GetCharacterPlacementW(HDC hdc,
864 LPCWSTR lpString,
865 int uCount,
866 int nMaxExtent,
867 GCP_RESULTSW *lpResults,
868 DWORD dwFlags)
869{
870 return FT2Module.Ft2GetCharacterPlacementW(hdc, lpString, uCount, nMaxExtent, lpResults, dwFlags);
871}
872
873
874/***********************************************************************
875 * FONT_mbtowc
876 *
877 * Returns a '\0' terminated Unicode translation of str using the
878 * charset of the currently selected font in hdc. If count is -1 then
879 * str is assumed to be '\0' terminated, otherwise it contains the
880 * number of bytes to convert. If plenW is non-NULL, on return it
881 * will point to the number of WCHARs (excluding the '\0') that have
882 * been written. If pCP is non-NULL, on return it will point to the
883 * codepage used in the conversion (NB, this may be CP_SYMBOL so watch
884 * out). The caller should free the returned LPWSTR from the process
885 * heap itself.
886 */
887LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
888{
889 UINT cp = CP_ACP;
890 INT lenW, i;
891 LPWSTR strW;
892 CHARSETINFO csi;
893 int charset = GetTextCharset(hdc);
894
895 if( IsDBCSEnv() && ( charset == 0 ))
896 cp = CP_ACP;
897 else
898 /* Hmm, nicely designed api this one! */
899 if(TranslateCharsetInfo((DWORD*)charset, &csi, TCI_SRCCHARSET))
900 cp = csi.ciACP;
901 else {
902 switch(charset) {
903 case OEM_CHARSET:
904 cp = GetOEMCP();
905 break;
906 case DEFAULT_CHARSET:
907 cp = GetACP();
908 break;
909
910 case VISCII_CHARSET:
911 case TCVN_CHARSET:
912 case KOI8_CHARSET:
913 case ISO3_CHARSET:
914 case ISO4_CHARSET:
915 /* FIXME: These have no place here, but because x11drv
916 enumerates fonts with these (made up) charsets some apps
917 might use them and then the FIXME below would become
918 annoying. Now we could pick the intended codepage for
919 each of these, but since it's broken anyway we'll just
920 use CP_ACP and hope it'll go away...
921 */
922 cp = CP_ACP;
923 break;
924
925
926 default:
927 dprintf(("Can't find codepage for charset %d\n", charset));
928 break;
929 }
930 }
931
932 dprintf(("cp == %d\n", cp));
933
934 if(count == -1) count = strlen(str);
935 if(cp != CP_SYMBOL) {
936 lenW = MultiByteToWideChar(cp, 0, str, count, NULL, 0);
937 strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
938 MultiByteToWideChar(cp, 0, str, count, strW, lenW);
939 } else {
940 lenW = count;
941 strW = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (lenW + 1) * sizeof(WCHAR));
942 for(i = 0; i < count; i++) strW[i] = (BYTE)str[i];
943 }
944 strW[lenW] = '\0';
945 dprintf(("mapped %s -> %ls\n", str, strW));
946 if(plenW) *plenW = lenW;
947 if(pCP) *pCP = cp;
948 return strW;
949}
950
951/*************************************************************************
952 * GetGlyphIndicesA [GDI32.@]
953 */
954DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
955 LPWORD pgi, DWORD flags)
956{
957 DWORD ret;
958 WCHAR *lpstrW;
959 INT countW;
960
961 dprintf(("GDI32: GetGlyphIndicesA (%p, %s, %d, %p, 0x%lx)\n",
962 hdc, lpstr, count, pgi, flags));
963
964 lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
965 ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
966 HeapFree(GetProcessHeap(), 0, lpstrW);
967
968 return ret;
969}
970
971/*************************************************************************
972 * GetGlyphIndicesW [GDI32.@]
973 */
974DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
975 LPWORD pgi, DWORD flags)
976{
977 DWORD ret;
978
979 dprintf(("GDI32: GetGlyphIndicesW (%ls, %d, %p, 0x%lx)",
980 lpstr, count, pgi, flags));
981
982 if(!hdc) return GDI_ERROR;
983
984 ret = FT2Module.Ft2GetGlyphIndices(hdc, lpstr, count , pgi, flags);
985 if(ret != GDI_ERROR) {
986 for(int i=0;i<ret;i++) {
987 dprintf(("GetGlyphIndices: %c (%x)-> %d", lpstr[i], lpstr[i], pgi[i]));
988 }
989 }
990 return ret;
991}
992
993/***********************************************************************
994 * GetGlyphOutlineA (GDI32.@)
995 */
996DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
997 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
998 LPVOID lpBuffer, const MAT2 *lpmat2 )
999{
1000 LPWSTR p = NULL;
1001 DWORD ret;
1002 UINT c;
1003
1004 if ((fuFormat & GGO_GLYPH_INDEX) == 0)
1005 {
1006 p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1007 if (p)
1008 {
1009 c = p[0];
1010 }
1011 else
1012 {
1013 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1014 return GDI_ERROR;
1015 }
1016 }
1017 else
1018 {
1019 c = uChar;
1020 }
1021
1022 ret = GetGlyphOutlineW (hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
1023
1024 if (p != NULL)
1025 {
1026 HeapFree (GetProcessHeap(), 0, p);
1027 }
1028
1029 return ret;
1030}
1031
1032/***********************************************************************
1033 * GetGlyphOutlineW (GDI32.@)
1034 */
1035DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1036 LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1037 LPVOID lpBuffer, const MAT2 *lpmat2 )
1038{
1039 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
1040
1041 dprintf(("GDI32: GetGlyphOutlineW(%p, %04x, %04x, %p, %ld, %p, %p)\n",
1042 pHps, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 ));
1043
1044 if (!hdc || !pHps)
1045 {
1046 SetLastError(ERROR_INVALID_PARAMETER);
1047 return GDI_ERROR;
1048 }
1049
1050 return FT2Module.Ft2GetGlyphOutline(pHps->hps, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2);
1051}
1052//******************************************************************************
1053//******************************************************************************
1054DWORD WIN32API GetKerningPairsA( HDC hdc, DWORD nNumPairs, LPKERNINGPAIR lpkrnpair)
1055{
1056 return O32_GetKerningPairs(hdc, nNumPairs, lpkrnpair);
1057}
1058//******************************************************************************
1059//******************************************************************************
Note: See TracBrowser for help on using the repository browser.