00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "a2dprec.h"
00035
00036 #if defined(__WXMSW__)
00037
00038 #include <wx/platform.h>
00039 #include <windows.h>
00040 #include <assert.h>
00041 #include <tchar.h>
00042 #include "wx/artbase/mswfont.h"
00043
00044
00045
00046
00047
00048 #if defined(__VISUALC__)
00049 #pragma warning(disable : 4127) // conditional expression is constant
00050 #endif
00051
00052
00053
00054 static LONG GetNextNameValue( HKEY key, LPCTSTR subkey, LPTSTR szName, LPTSTR szData );
00055 static BOOL GetWinVer( LPTSTR lpszVersion, int nVersionSize, int *nVersion );
00056
00057
00058
00059 #define WUNKNOWNSTR _T("unknown Windows version")
00060
00061 #define W95STR _T("Windows 95")
00062 #define W95SP1STR _T("Windows 95 SP1")
00063 #define W95OSR2STR _T("Windows 95 OSR2")
00064 #define W98STR _T("Windows 98")
00065 #define W98SP1STR _T("Windows 98 SP1")
00066 #define W98SESTR _T("Windows 98 SE")
00067 #define WMESTR _T("Windows ME")
00068
00069 #define WNT351STR _T("Windows NT 3.51")
00070 #define WNT4STR _T("Windows NT 4")
00071 #define W2KSTR _T("Windows 2000")
00072 #define WXPSTR _T("Windows XP")
00073 #define W2003STR _T("Windows Server 2003")
00074 #define WUNKNOWNPSTR _T("Windows Unknown")
00075
00076 #define WCESTR _T("Windows CE")
00077
00078
00079 #define WUNKNOWN 0
00080
00081 #define W9XFIRST 1
00082 #define W95 1
00083 #define W95SP1 2
00084 #define W95OSR2 3
00085 #define W98 4
00086 #define W98SP1 5
00087 #define W98SE 6
00088 #define WME 7
00089 #define W9XLAST 99
00090
00091 #define WNTFIRST 101
00092 #define WNT351 101
00093 #define WNT4 102
00094 #define W2K 103
00095 #define WXP 104
00096 #define W2003 105
00097 #define WNTLAST 199
00098
00099 #define WCEFIRST 201
00100 #define WCE 201
00101 #define WCELAST 299
00102
00103
00104
00105
00106
00107
00108 typedef struct _tagFONT_PROPERTIES_ANSI
00109 {
00110 char csName[1024];
00111 char csCopyright[1024];
00112 char csTrademark[1024];
00113 char csFamily[1024];
00114 }
00115 FONT_PROPERTIES_ANSI;
00116
00117 typedef struct _tagTT_OFFSET_TABLE
00118 {
00119 USHORT uMajorVersion;
00120 USHORT uMinorVersion;
00121 USHORT uNumOfTables;
00122 USHORT uSearchRange;
00123 USHORT uEntrySelector;
00124 USHORT uRangeShift;
00125 }
00126 TT_OFFSET_TABLE;
00127
00128 typedef struct _tagTT_TABLE_DIRECTORY
00129 {
00130 char szTag[4];
00131 ULONG uCheckSum;
00132 ULONG uOffset;
00133 ULONG uLength;
00134 }
00135 TT_TABLE_DIRECTORY;
00136
00137 typedef struct _tagTT_NAME_TABLE_HEADER
00138 {
00139 USHORT uFSelector;
00140 USHORT uNRCount;
00141 USHORT uStorageOffset;
00142 }
00143 TT_NAME_TABLE_HEADER;
00144
00145 typedef struct _tagTT_NAME_RECORD
00146 {
00147 USHORT uPlatformID;
00148 USHORT uEncodingID;
00149 USHORT uLanguageID;
00150 USHORT uNameID;
00151 USHORT uStringLength;
00152 USHORT uStringOffset;
00153 }
00154 TT_NAME_RECORD;
00155
00156 #define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
00157 #define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 BOOL GetFontFile( LPCTSTR lpszFontName,
00186 LPTSTR lpszDisplayName,
00187 int nDisplayNameSize,
00188 LPTSTR lpszFontFile,
00189 int nFontFileSize )
00190 {
00191 assert( lpszFontName && lpszFontName[0] != 0 );
00192 if ( !lpszFontName || lpszFontName[0] == 0 )
00193 return FALSE;
00194
00195 assert( lpszDisplayName );
00196 if ( !lpszDisplayName )
00197 return FALSE;
00198
00199 assert( lpszFontFile );
00200 if ( !lpszFontFile )
00201 return FALSE;
00202
00203 lpszDisplayName[0] = _T( '\0' );
00204 lpszFontFile[0] = _T( '\0' );
00205
00206 TCHAR szName[2 * MAX_PATH];
00207 TCHAR szData[2 * MAX_PATH];
00208
00209 int nVersion;
00210 TCHAR szVersion[100];
00211 GetWinVer( szVersion, sizeof( szVersion ) / sizeof( TCHAR ) - 1, &nVersion );
00212
00213 TCHAR szFontPath[1000];
00214
00215 if ( ( nVersion >= WNTFIRST ) && ( nVersion <= WNTLAST ) )
00216 _tcscpy( szFontPath, _T( "Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts" ) );
00217 else
00218 _tcscpy( szFontPath, _T( "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts" ) );
00219
00220 BOOL bResult = FALSE;
00221
00222 while ( GetNextNameValue( HKEY_LOCAL_MACHINE, szFontPath, szName, szData ) == ERROR_SUCCESS )
00223 {
00224 if ( _tcsnicmp( lpszFontName, szName, _tcslen( lpszFontName ) ) == 0 )
00225 {
00226 _tcsncpy( lpszDisplayName, szName, nDisplayNameSize - 1 );
00227 _tcsncpy( lpszFontFile, szData, nFontFileSize - 1 );
00228 bResult = TRUE;
00229 break;
00230 }
00231
00232 szFontPath[0] = _T( '\0' );
00233 }
00234
00235 GetNextNameValue( HKEY_LOCAL_MACHINE, NULL, NULL, NULL );
00236
00237 return bResult;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 BOOL GetFontProperties( LPCTSTR lpszFilePath, FONT_PROPERTIES * lpFontPropsX )
00253 {
00254 FONT_PROPERTIES_ANSI fp;
00255 FONT_PROPERTIES_ANSI * lpFontProps = &fp;
00256
00257 memset( lpFontProps, 0, sizeof( FONT_PROPERTIES_ANSI ) );
00258
00259 HANDLE hFile = INVALID_HANDLE_VALUE;
00260 hFile = ::CreateFile( lpszFilePath,
00261 GENERIC_READ,
00262 0,
00263 NULL,
00264 OPEN_ALWAYS,
00265 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
00266 NULL );
00267
00268 if ( hFile == INVALID_HANDLE_VALUE )
00269 {
00270 return FALSE;
00271 }
00272
00273
00274 DWORD dwFileSize = ::GetFileSize( hFile, NULL );
00275
00276 if ( dwFileSize == INVALID_FILE_SIZE )
00277 {
00278 ::CloseHandle( hFile );
00279 return FALSE;
00280 }
00281
00282
00283 HANDLE hMappedFile = NULL;
00284 hMappedFile = ::CreateFileMapping( hFile,
00285 NULL,
00286 PAGE_READONLY,
00287 0,
00288 dwFileSize,
00289 NULL );
00290
00291 if ( hMappedFile == NULL )
00292 {
00293 ::CloseHandle( hFile );
00294 return FALSE;
00295 }
00296
00297 LPBYTE lpMapAddress = ( LPBYTE ) ::MapViewOfFile( hMappedFile,
00298 FILE_MAP_READ,
00299 0,
00300 0,
00301 0 );
00302
00303 if ( lpMapAddress == NULL )
00304 {
00305 ::CloseHandle( hMappedFile );
00306 ::CloseHandle( hFile );
00307 return FALSE;
00308 }
00309
00310 BOOL bRetVal = FALSE;
00311 int index = 0;
00312
00313 TT_OFFSET_TABLE ttOffsetTable;
00314 memcpy( &ttOffsetTable, &lpMapAddress[index], sizeof( TT_OFFSET_TABLE ) );
00315 index += sizeof( TT_OFFSET_TABLE );
00316
00317 ttOffsetTable.uNumOfTables = SWAPWORD( ttOffsetTable.uNumOfTables );
00318 ttOffsetTable.uMajorVersion = SWAPWORD( ttOffsetTable.uMajorVersion );
00319 ttOffsetTable.uMinorVersion = SWAPWORD( ttOffsetTable.uMinorVersion );
00320
00321
00322 if ( ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0 )
00323 return bRetVal;
00324
00325 TT_TABLE_DIRECTORY tblDir;
00326 memset( &tblDir, 0, sizeof( TT_TABLE_DIRECTORY ) );
00327 BOOL bFound = FALSE;
00328 char szTemp[4096];
00329 memset( szTemp, 0, sizeof( szTemp ) );
00330
00331 for ( int i = 0; i < ttOffsetTable.uNumOfTables; i++ )
00332 {
00333
00334 memcpy( &tblDir, &lpMapAddress[index], sizeof( TT_TABLE_DIRECTORY ) );
00335 index += sizeof( TT_TABLE_DIRECTORY );
00336
00337 strncpy( szTemp, tblDir.szTag, 4 );
00338 if ( stricmp( szTemp, "name" ) == 0 )
00339 {
00340 bFound = TRUE;
00341 tblDir.uLength = SWAPLONG( tblDir.uLength );
00342 tblDir.uOffset = SWAPLONG( tblDir.uOffset );
00343 break;
00344 }
00345 else if ( szTemp[0] == 0 )
00346 {
00347 break;
00348 }
00349 }
00350
00351 if ( bFound )
00352 {
00353 index = tblDir.uOffset;
00354
00355 TT_NAME_TABLE_HEADER ttNTHeader;
00356 memcpy( &ttNTHeader, &lpMapAddress[index], sizeof( TT_NAME_TABLE_HEADER ) );
00357 index += sizeof( TT_NAME_TABLE_HEADER );
00358
00359 ttNTHeader.uNRCount = SWAPWORD( ttNTHeader.uNRCount );
00360 ttNTHeader.uStorageOffset = SWAPWORD( ttNTHeader.uStorageOffset );
00361 TT_NAME_RECORD ttRecord;
00362 bFound = FALSE;
00363
00364 for ( int i = 0;
00365 i < ttNTHeader.uNRCount &&
00366 ( lpFontProps->csCopyright[0] == 0 ||
00367 lpFontProps->csName[0] == 0 ||
00368 lpFontProps->csTrademark[0] == 0 ||
00369 lpFontProps->csFamily[0] == 0 );
00370 i++ )
00371 {
00372 memcpy( &ttRecord, &lpMapAddress[index], sizeof( TT_NAME_RECORD ) );
00373 index += sizeof( TT_NAME_RECORD );
00374
00375 ttRecord.uNameID = SWAPWORD( ttRecord.uNameID );
00376 ttRecord.uStringLength = SWAPWORD( ttRecord.uStringLength );
00377 ttRecord.uStringOffset = SWAPWORD( ttRecord.uStringOffset );
00378
00379 if ( ttRecord.uNameID == 1 || ttRecord.uNameID == 0 || ttRecord.uNameID == 7 )
00380 {
00381 int nPos = index;
00382
00383 index = tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset;
00384
00385 memset( szTemp, 0, sizeof( szTemp ) );
00386
00387 memcpy( szTemp, &lpMapAddress[index], ttRecord.uStringLength );
00388 index += ttRecord.uStringLength;
00389
00390 if ( szTemp[0] != 0 )
00391 {
00392 assert( strlen( szTemp ) < sizeof( lpFontProps->csName ) );
00393
00394 switch ( ttRecord.uNameID )
00395 {
00396 case 0:
00397 if ( lpFontProps->csCopyright[0] == 0 )
00398 strncpy( lpFontProps->csCopyright, szTemp,
00399 sizeof( lpFontProps->csCopyright ) - 1 );
00400 break;
00401
00402 case 1:
00403 if ( lpFontProps->csFamily[0] == 0 )
00404 strncpy( lpFontProps->csFamily, szTemp,
00405 sizeof( lpFontProps->csFamily ) - 1 );
00406 bRetVal = TRUE;
00407 break;
00408
00409 case 4:
00410 if ( lpFontProps->csName[0] == 0 )
00411 strncpy( lpFontProps->csName, szTemp,
00412 sizeof( lpFontProps->csName ) - 1 );
00413 break;
00414
00415 case 7:
00416 if ( lpFontProps->csTrademark[0] == 0 )
00417 strncpy( lpFontProps->csTrademark, szTemp,
00418 sizeof( lpFontProps->csTrademark ) - 1 );
00419 break;
00420
00421 default:
00422 break;
00423 }
00424 }
00425 index = nPos;
00426 }
00427 }
00428 }
00429
00430 ::UnmapViewOfFile( lpMapAddress );
00431 ::CloseHandle( hMappedFile );
00432 ::CloseHandle( hFile );
00433
00434 if ( lpFontProps->csName[0] == 0 )
00435 strcpy( lpFontProps->csName, lpFontProps->csFamily );
00436
00437 memset( lpFontPropsX, 0, sizeof( FONT_PROPERTIES ) );
00438
00439 #ifdef _UNICODE
00440 ::MultiByteToWideChar( CP_ACP, 0, lpFontProps->csName, -1, lpFontPropsX->csName,
00441 sizeof( lpFontPropsX->csName ) / sizeof( TCHAR ) - 1 );
00442 ::MultiByteToWideChar( CP_ACP, 0, lpFontProps->csCopyright, -1, lpFontPropsX->csCopyright,
00443 sizeof( lpFontPropsX->csCopyright ) / sizeof( TCHAR ) - 1 );
00444 ::MultiByteToWideChar( CP_ACP, 0, lpFontProps->csTrademark, -1, lpFontPropsX->csTrademark,
00445 sizeof( lpFontPropsX->csTrademark ) / sizeof( TCHAR ) - 1 );
00446 ::MultiByteToWideChar( CP_ACP, 0, lpFontProps->csFamily, -1, lpFontPropsX->csFamily,
00447 sizeof( lpFontPropsX->csFamily ) / sizeof( TCHAR ) - 1 );
00448 #else
00449 strcpy( lpFontPropsX->csName, lpFontProps->csName );
00450 strcpy( lpFontPropsX->csCopyright, lpFontProps->csCopyright );
00451 strcpy( lpFontPropsX->csTrademark, lpFontProps->csTrademark );
00452 strcpy( lpFontPropsX->csFamily, lpFontProps->csFamily );
00453 #endif
00454
00455 return bRetVal;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 static LONG GetNextNameValue( HKEY key, LPCTSTR pszSubkey, LPTSTR pszName, LPTSTR pszData )
00480 {
00481 static HKEY hkey = NULL;
00482 static DWORD dwIndex = 0;
00483 LONG retval;
00484
00485
00486 if ( pszSubkey == NULL && pszName == NULL && pszData == NULL )
00487 {
00488 if ( hkey )
00489 RegCloseKey( hkey );
00490 hkey = NULL;
00491 return ERROR_SUCCESS;
00492 }
00493
00494
00495 if ( pszSubkey && pszSubkey[0] != 0 )
00496 {
00497 retval = RegOpenKeyEx( key, pszSubkey, 0, KEY_QUERY_VALUE, &hkey );
00498 if ( retval != ERROR_SUCCESS )
00499 {
00500 return retval;
00501 }
00502 else
00503 {}
00504 dwIndex = 0;
00505 }
00506 else
00507 {
00508 dwIndex++;
00509 }
00510
00511 assert( pszName != NULL && pszData != NULL );
00512
00513 *pszName = 0;
00514 *pszData = 0;
00515
00516 TCHAR szValueName[MAX_PATH];
00517 DWORD dwValueNameSize = sizeof( szValueName ) - 1;
00518 BYTE szValueData[MAX_PATH];
00519 DWORD dwValueDataSize = sizeof( szValueData ) - 1;
00520 DWORD dwType = 0;
00521
00522 retval = RegEnumValue( hkey, dwIndex, szValueName, &dwValueNameSize, NULL,
00523 &dwType, szValueData, &dwValueDataSize );
00524 if ( retval == ERROR_SUCCESS )
00525 {
00526 lstrcpy( pszName, ( LPTSTR )szValueName );
00527 lstrcpy( pszData, ( LPTSTR )szValueData );
00528 }
00529 else
00530 {}
00531
00532 return retval;
00533 }
00534
00535
00536
00537 #ifndef VER_PLATFORM_WIN32s
00538 #define VER_PLATFORM_WIN32s 0
00539 #endif
00540 #ifndef VER_PLATFORM_WIN32_WINDOWS
00541 #define VER_PLATFORM_WIN32_WINDOWS 1
00542 #endif
00543 #ifndef VER_PLATFORM_WIN32_NT
00544 #define VER_PLATFORM_WIN32_NT 2
00545 #endif
00546 #ifndef VER_PLATFORM_WIN32_CE
00547 #define VER_PLATFORM_WIN32_CE 3
00548 #endif
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 static BOOL GetWinVer( LPTSTR lpszVersion, int nVersionSize, int *pnVersion )
00591 {
00592 _tcsncpy( lpszVersion, WUNKNOWNSTR, nVersionSize - 1 );
00593 *pnVersion = WUNKNOWN;
00594
00595 TCHAR *cp = WUNKNOWNSTR;
00596
00597 OSVERSIONINFO osinfo;
00598 osinfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
00599
00600 if ( !GetVersionEx( &osinfo ) )
00601 return FALSE;
00602
00603 DWORD dwPlatformId = osinfo.dwPlatformId;
00604 DWORD dwMinorVersion = osinfo.dwMinorVersion;
00605 DWORD dwMajorVersion = osinfo.dwMajorVersion;
00606 DWORD dwBuildNumber = osinfo.dwBuildNumber & 0xFFFF;
00607
00608 if ( ( dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) && ( dwMajorVersion == 4 ) )
00609 {
00610 if ( ( dwMinorVersion < 10 ) && ( dwBuildNumber == 950 ) )
00611 {
00612 cp = W95STR;
00613 *pnVersion = W95;
00614 }
00615 else if ( ( dwMinorVersion < 10 ) &&
00616 ( ( dwBuildNumber > 950 ) && ( dwBuildNumber <= 1080 ) ) )
00617 {
00618 cp = W95SP1STR;
00619 *pnVersion = W95SP1;
00620 }
00621 else if ( ( dwMinorVersion < 10 ) && ( dwBuildNumber > 1080 ) )
00622 {
00623 cp = W95OSR2STR;
00624 *pnVersion = W95OSR2;
00625 }
00626 else if ( ( dwMinorVersion == 10 ) && ( dwBuildNumber == 1998 ) )
00627 {
00628 cp = W98STR;
00629 *pnVersion = W98;
00630 }
00631 else if ( ( dwMinorVersion == 10 ) &&
00632 ( ( dwBuildNumber > 1998 ) && ( dwBuildNumber < 2183 ) ) )
00633 {
00634 cp = W98SP1STR;
00635 *pnVersion = W98SP1;
00636 }
00637 else if ( ( dwMinorVersion == 10 ) && ( dwBuildNumber >= 2183 ) )
00638 {
00639 cp = W98SESTR;
00640 *pnVersion = W98SE;
00641 }
00642 else if ( dwMinorVersion == 90 )
00643 {
00644 cp = WMESTR;
00645 *pnVersion = WME;
00646 }
00647 }
00648 else if ( dwPlatformId == VER_PLATFORM_WIN32_NT )
00649 {
00650 if ( ( dwMajorVersion == 3 ) && ( dwMinorVersion == 51 ) )
00651 {
00652 cp = WNT351STR;
00653 *pnVersion = WNT351;
00654 }
00655 else if ( ( dwMajorVersion == 4 ) && ( dwMinorVersion == 0 ) )
00656 {
00657 cp = WNT4STR;
00658 *pnVersion = WNT4;
00659 }
00660 else if ( ( dwMajorVersion == 5 ) && ( dwMinorVersion == 0 ) )
00661 {
00662 cp = W2KSTR;
00663 *pnVersion = W2K;
00664 }
00665 else if ( ( dwMajorVersion == 5 ) && ( dwMinorVersion == 1 ) )
00666 {
00667 cp = WXPSTR;
00668 *pnVersion = WXP;
00669 }
00670 else if ( ( dwMajorVersion == 5 ) && ( dwMinorVersion == 2 ) )
00671 {
00672 cp = W2003STR;
00673 *pnVersion = W2003;
00674 }
00675
00676 }
00677 else if ( dwPlatformId == VER_PLATFORM_WIN32_CE )
00678 {
00679 cp = WCESTR;
00680 *pnVersion = WCE;
00681 }
00682
00683 _tcsncpy( lpszVersion, cp, nVersionSize - 1 );
00684
00685 return TRUE;
00686 }
00687
00688 #endif //defined(__WXMSW__)