Changeset 21304 for trunk/src/gdi32/fontres.cpp
- Timestamp:
- Jun 18, 2009, 12:12:33 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gdi32/fontres.cpp
r10373 r21304 26 26 #include <dbglog.h> 27 27 #include <unicode.h> 28 #include <stats.h> 28 #include <heapstring.h> 29 #include <neexe.h> 29 30 #include <objhandle.h> 31 #include <font.h> 32 #include <vmutex.h> 33 #include "ft2supp.h" 34 30 35 #include "oslibgpi.h" 31 36 … … 48 53 49 54 static SCALABLEFONTS *publicfonts = NULL; 50 static CRITICAL_SECTION fntcritsect = {0};51 52 #define FntLock() EnterCriticalSection(&fntcritsect)53 #define FntUnlock() LeaveCriticalSection(&fntcritsect)55 static VMutex fntmutex; 56 57 #define FntLock() fntmutex.enter() 58 #define FntUnlock() fntmutex.leave() 54 59 55 60 … … 85 90 //****************************************************************************** 86 91 //****************************************************************************** 92 static LPVOID ReadEntireFile(LPSTR lpszFileName, DWORD *lpdwSize = NULL) 93 { 94 HFILE hFile = INVALID_HANDLE_VALUE; 95 96 DWORD dwSize, dwBytesRead, ret; 97 LPVOID lpFileData = NULL; 98 99 hFile = CreateFileA(lpszFileName, 100 GENERIC_READ, 101 FILE_SHARE_READ | FILE_SHARE_WRITE, 102 NULL, 103 OPEN_EXISTING, 104 0, 105 NULL); 106 107 if(hFile == INVALID_HANDLE_VALUE) { 108 DebugInt3(); 109 goto failure; 110 } 111 //determine filesize 112 dwSize = SetFilePointer(hFile, 0, NULL, FILE_END); 113 SetFilePointer(hFile, 0, NULL, FILE_BEGIN); 114 115 //allocate memory to hold the entire file 116 lpFileData = (char *)malloc(dwSize); 117 if(lpFileData == NULL) { 118 DebugInt3(); 119 goto failure; 120 } 121 //and read it 122 ret = ReadFile(hFile, lpFileData, dwSize, &dwBytesRead, NULL); 123 if(ret == FALSE || dwBytesRead != dwSize) { 124 DebugInt3(); 125 goto failure; 126 } 127 if(lpdwSize) *lpdwSize = dwSize; 128 129 CloseHandle(hFile); 130 return lpFileData; 131 132 failure: 133 if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); 134 if(lpFileData) free(lpFileData); 135 return NULL; 136 } 137 //****************************************************************************** 138 //****************************************************************************** 87 139 DWORD WIN32API GetFontData(HDC hdc, DWORD dwTable, 88 140 DWORD dwOffset, 89 141 LPVOID lpvBuffer, 90 DWORD dbData) 91 { 92 dprintf(("GDI32: GetFontData, not implemented (GDI_ERROR)\n")); 93 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 142 DWORD cbData) 143 { 144 HFONT hFont; 145 SCALABLEFONTS *font; 146 147 dprintf(("GDI32: GetFontData, partially implemented")); 148 149 hFont = GetCurrentObject(hdc, OBJ_FONT); 150 if(hFont == 0) { 151 SetLastError(ERROR_INVALID_PARAMETER); 152 return GDI_ERROR; 153 } 154 font = (SCALABLEFONTS *)ObjQueryHandleGDI32Data(hFont, HNDL_FONT); 155 if(font == NULL) { 156 return FT2Module.Ft2GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData); 157 } 158 159 if(font->pFontData == NULL) 160 { 161 font->pFontData = (char *)ReadEntireFile(font->szFileName, &font->dwFontSize); 162 if(!font->pFontData) return GDI_ERROR; 163 } 164 165 cbData = min(cbData, font->dwFontSize); 166 if(dwTable == 0 && dwOffset == 0) { 167 if(lpvBuffer == NULL) return font->dwFontSize; 168 169 memcpy(lpvBuffer, font->pFontData, cbData); 170 return cbData; 171 } 172 173 //todo: parse TTF structure (haven't seen anybody rely on that yet) 94 174 95 175 return(GDI_ERROR); 96 176 } 97 177 //****************************************************************************** 178 //TODO: supposed to support more than only .fon files 98 179 //****************************************************************************** 99 180 int WIN32API AddFontResourceA(LPCSTR szFont) 100 181 { 101 HINSTANCE hInstance; 182 DWORD ret, alignment, nrFonts, fontOrdinal, i; 183 PIMAGE_DOS_HEADER pDosHdr = NULL; 184 PIMAGE_OS2_HEADER pNEHdr; 185 struct resource_typeinfo_s *pResInfo; 186 struct resource_nameinfo_s *pNameInfo; 187 LPFONTDIR16 pFontDir = NULL; 188 char *pFontNameId; 189 char *pResNameTable; 190 char *pFontPath, *newname = NULL, *extension; 191 char szFamily[32], szFace[32]; 102 192 103 193 dprintf(("GDI32: AddFontResourceA %s", szFont)); 104 hInstance = LoadLibraryA(szFont); 105 if(hInstance) { 106 dprintf(("AddFontResourceA: executable file; NOT IMPLEMENTED")); 107 FreeLibrary(hInstance); 108 return 1; 109 } 194 195 if(GetFileAttributesA(szFont) == -1) { 196 dprintf(("WARNING: Font res file doesn't exists")); 197 SetLastError(ERROR_INVALID_PARAMETER); 198 return FALSE; 199 } 200 201 //Support for raw .ttf files as well 202 newname = strupr(strdup(szFont)); 203 extension = strrchr(newname, '.'); 204 if (!strcmp(extension, ".TTF")) 205 { 206 //get font family and face names 207 OSLibGpiQueryFontName(newname, szFamily, szFace, sizeof(szFamily)); 208 } 209 else 210 { 211 pDosHdr = (PIMAGE_DOS_HEADER)ReadEntireFile((LPSTR)szFont); 212 if(!pDosHdr) return FALSE; 213 214 pNEHdr = (PIMAGE_OS2_HEADER) ((char *)pDosHdr + pDosHdr->e_lfanew); 215 if(pDosHdr->e_magic != IMAGE_DOS_SIGNATURE || 216 pNEHdr->ne_magic != IMAGE_OS2_SIGNATURE) { 217 dprintf(("Unknown file format")); 218 goto failure; 219 } 220 221 pResInfo = (struct resource_typeinfo_s *)((char *)pNEHdr + pNEHdr->ne_rsrctab); 222 alignment = *(WORD *)pResInfo; 223 pResInfo = (struct resource_typeinfo_s *)((char *)pResInfo+sizeof(WORD)); 224 225 //first resource is a font directory 226 if(pResInfo->type_id != NE_RSCTYPE_FONTDIR && pResInfo->count != 1) { 227 dprintf(("Unknown file format")); 228 goto failure; 229 } 230 pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1); 231 pFontDir = (LPFONTDIR16)((char *)pDosHdr + (pNameInfo->offset << alignment)); 232 //first word = length followed by the string (not terminated) 233 pFontNameId = (char *)pResInfo - sizeof(WORD) + pNameInfo->id; 234 235 nrFonts = *(WORD *)pFontDir; 236 fontOrdinal = *((WORD *)pFontDir+1); 237 pFontDir = (LPFONTDIR16)((char *)pFontDir + 2*sizeof(WORD)); 238 239 pResNameTable = (char *)pNEHdr + pNEHdr->ne_restab; 240 241 //second resource is the absolute path of the TTF file 242 pResInfo = (struct resource_typeinfo_s *)(pNameInfo+1); 243 if(pResInfo->type_id != 0x80CC && pResInfo->count != 1) { 244 dprintf(("Unknown file format")); 245 goto failure; 246 } 247 pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1); 248 pFontPath = ((char *)pDosHdr + (pNameInfo->offset << alignment)); 249 250 free(newname); 251 252 //GPI makes assumptions about the file based on the extention (d'oh) 253 newname = strdup(pFontPath); 254 extension = strrchr(newname, '.'); 255 256 strcpy(extension, ".TTF"); 257 CopyFileA(pFontPath, newname, FALSE); 258 } 259 260 //Load the TrueType font 261 ret = OSLibGpiLoadFonts(newname); 262 if(ret == FALSE) { 263 dprintf(("OSLibGpiLoadFonts %s failed!!", pFontPath)); 264 goto failure; 265 } 266 267 //add to the list of known public fonts that we added before 268 if(publicfonts == NULL) { 269 publicfonts = (SCALABLEFONTS*)malloc(MAX_PUBLICFONTS*sizeof(SCALABLEFONTS)); 270 if(publicfonts == NULL) { 271 DebugInt3(); 272 goto failure; 273 } 274 memset(publicfonts, 0, MAX_PUBLICFONTS*sizeof(SCALABLEFONTS)); 275 } 276 FntLock(); 277 for(i=0;i<MAX_PUBLICFONTS;i++) { 278 if(publicfonts[i].szFaceName[0] == 0) { 279 break; 280 } 281 } 282 if(i == MAX_PUBLICFONTS) { 283 FntUnlock(); 284 DebugInt3(); 285 goto failure; 286 } 287 strncpy(publicfonts[i].szFileName, newname, sizeof(publicfonts[i].szFileName)); 288 if (pFontDir) 289 strncpy(publicfonts[i].szFaceName, pFontDir->szDeviceName, sizeof(publicfonts[i].szFaceName)); 290 else 291 strncpy(publicfonts[i].szFaceName, szFace, sizeof(publicfonts[i].szFaceName)); 292 strncpy(publicfonts[i].szFontResName, szFont, sizeof(publicfonts[i].szFontResName)); 293 publicfonts[i].pFontData = NULL; 294 FntUnlock(); 295 296 free(newname); 297 free(pDosHdr); 110 298 return 1; 299 300 failure: 301 if(pDosHdr) free(pDosHdr); 302 if(newname) free(newname); 303 return 0; 111 304 } 112 305 //****************************************************************************** … … 115 308 { 116 309 char *astring = UnicodeToAsciiString((LPWSTR)szFont); 117 BOOL rc;310 int ret; 118 311 119 312 dprintf(("GDI32: AddFontResourceW")); 120 // NOTE: This will not work as is (needs UNICODE support) 121 rc = AddFontResourceA(astring); 313 ret = AddFontResourceA(astring); 122 314 FreeAsciiString(astring); 123 return r c;315 return ret; 124 316 } 125 317 //****************************************************************************** … … 127 319 BOOL WIN32API RemoveFontResourceA(LPCSTR lpszFont) 128 320 { 321 BOOL ret; 322 129 323 dprintf(("GDI32: RemoveFontResourceA %s", lpszFont)); 324 325 if(!publicfonts) { 326 dprintf(("WARNING: font not found in our list!!")); 130 327 return FALSE; 328 } 329 FntLock(); 330 for(int i=0;i<MAX_PUBLICFONTS;i++) { 331 if(strcmp(publicfonts[i].szFontResName, lpszFont) == 0) 332 { 333 ret = OSLibGpiUnloadFonts(publicfonts[i].szFileName); 334 DeleteFileA(publicfonts[i].szFileName); 335 336 if(publicfonts[i].pFontData) free(publicfonts[i].pFontData); 337 publicfonts[i].pFontData = 0; 338 publicfonts[i].szFileName[0] = 0; 339 publicfonts[i].szFaceName[0] = 0; 340 break; 341 } 342 } 343 FntUnlock(); 344 if(i == MAX_PUBLICFONTS) { 345 dprintf(("WARNING: font not found in our list!!")); 346 // no need to trap on a warning DebugInt3(); 347 return FALSE; 348 } 349 return ret; 131 350 } 132 351 //****************************************************************************** … … 135 354 { 136 355 char *astring = UnicodeToAsciiString((LPWSTR)szFont); 137 BOOL rc;356 BOOL ret; 138 357 139 358 dprintf(("GDI32: RemoveFontResourceW")); 140 r c= RemoveFontResourceA(astring);359 ret = RemoveFontResourceA(astring); 141 360 FreeAsciiString(astring); 142 return (rc);361 return ret; 143 362 } 144 363 /***************************************************************************** … … 163 382 LPCSTR lpszCurrentPath) 164 383 { 165 dprintf(("GDI32: CreateScalableFontResourceA %x %s %s %s not implemented", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath)); 166 167 // return OSLibGpiLoadFonts((LPSTR)lpszFontFile); 384 HRSRC hRsrc; 385 HINSTANCE hGdi32; 386 HGLOBAL handle; 387 DWORD dwSize; 388 LPVOID lpData, lpCopy = NULL; 389 HANDLE hFile = 0; 390 DWORD ret, dwBytesWritten, alignment, nrFonts, fontOrdinal, len; 391 PIMAGE_DOS_HEADER pDosHdr; 392 PIMAGE_OS2_HEADER pNEHdr; 393 struct resource_typeinfo_s *pResInfo; 394 struct resource_nameinfo_s *pNameInfo; 395 LPFONTDIR16 pFontDir; 396 char *pFontNameId; 397 char *pResNameTable; 398 char *pFontPath, *newname, *extension; 399 char szFamily[32], szFace[32]; 400 401 dprintf(("GDI32: CreateScalableFontResourceA %x %s %s %s partly implemented", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath)); 402 403 if(lpszCurrentPath != NULL) { 404 //figure out which possibilities exist 405 DebugInt3(); 406 return FALSE; 407 } 408 409 //This function is supposed to create a font resource file (.fot; NE dll with 410 //references to the TTF file (absolute path)) 411 412 if(GetFileAttributesA(lpszFontRes) != -1) { 413 dprintf(("WARNING: Font res file already exists")); 414 SetLastError(ERROR_INVALID_PARAMETER); 415 return FALSE; 416 } 417 418 //fetch our font resource file example 419 hGdi32 = GetModuleHandleA("GDI32"); 420 hRsrc = FindResourceA( hGdi32, TESTFONT_RESNAME, RT_RCDATAA ); 421 if(!hRsrc) { 422 dprintf(("WARNING: Test font file resource not found!!")); 423 DebugInt3(); 424 return FALSE; 425 } 426 handle = LoadResource(hGdi32, hRsrc); 427 dwSize = SizeofResource(hGdi32, hRsrc); 428 lpData = LockResource(handle); 429 if(!dwSize || !handle || !lpData) { 430 dprintf(("WARNING: Test font file resource not loaded/locked!!")); 431 DebugInt3(); 432 return FALSE; 433 } 434 lpCopy = malloc(dwSize); 435 if(lpCopy == NULL) { 436 DebugInt3(); 437 return FALSE; 438 } 439 memcpy(lpCopy, lpData, dwSize); 440 441 pDosHdr = (PIMAGE_DOS_HEADER)lpCopy; 442 pNEHdr = (PIMAGE_OS2_HEADER) ((char *)pDosHdr + pDosHdr->e_lfanew); 443 if(pDosHdr->e_magic != IMAGE_DOS_SIGNATURE || 444 pNEHdr->ne_magic != IMAGE_OS2_SIGNATURE) { 445 dprintf(("Unknown file format")); 446 goto failure; 447 } 448 449 pResInfo = (struct resource_typeinfo_s *)((char *)pNEHdr + pNEHdr->ne_rsrctab); 450 alignment = *(WORD *)pResInfo; 451 pResInfo = (struct resource_typeinfo_s *)((char *)pResInfo+sizeof(WORD)); 452 453 //first resource is a font directory 454 if(pResInfo->type_id != NE_RSCTYPE_FONTDIR && pResInfo->count != 1) { 455 dprintf(("Unknown file format")); 456 goto failure; 457 } 458 pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1); 459 pFontDir = (LPFONTDIR16)((char *)pDosHdr + (pNameInfo->offset << alignment)); 460 //first word = length followed by the string (not terminated) 461 pFontNameId = (char *)pResInfo - sizeof(WORD) + pNameInfo->id; 462 463 //GPI makes assumptions about the file based on the extention (d'oh) 464 newname = strdup(lpszFontFile); 465 extension = strrchr(newname, '.'); 466 467 strcpy(extension, ".TTF"); 468 CopyFileA(lpszFontFile, newname, FALSE); 469 470 //get font family and face names 471 OSLibGpiQueryFontName(newname, szFamily, szFace, sizeof(szFamily)); 472 473 DeleteFileA(newname); 474 free(newname); 475 476 nrFonts = *(WORD *)pFontDir; 477 fontOrdinal = *((WORD *)pFontDir+1); 478 pFontDir = (LPFONTDIR16)((char *)pFontDir + 2*sizeof(WORD)); 479 480 //copy family and face names to fontdir structure 481 len = strlen(szFamily); 482 strcpy(pFontDir->szDeviceName, szFamily); 483 strcpy(pFontDir->szDeviceName + len + 1, szFace); 484 485 dprintf(("Family %s, Face %s", szFamily, szFace)); 486 487 pResNameTable = (char *)pNEHdr + pNEHdr->ne_restab; 488 489 //second resource is the absolute path of the TTF file 490 pResInfo = (struct resource_typeinfo_s *)(pNameInfo+1); 491 if(pResInfo->type_id != 0x80CC && pResInfo->count != 1) { 492 dprintf(("Unknown file format")); 493 goto failure; 494 } 495 pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1); 496 pFontPath = ((char *)pDosHdr + (pNameInfo->offset << alignment)); 497 //overwrite absolute font path 498 strcpy(pFontPath, lpszFontFile); 499 pNameInfo->length = strlen(lpszFontFile)+1; 500 501 hFile = CreateFileA(lpszFontRes, 502 GENERIC_READ | GENERIC_WRITE, 503 FILE_SHARE_READ | FILE_SHARE_WRITE, 504 NULL, 505 CREATE_NEW, 506 0, 507 NULL); 508 509 if(hFile == INVALID_HANDLE_VALUE) { 510 DebugInt3(); 511 goto failure; 512 } 513 ret = WriteFile(hFile, lpCopy, dwSize, &dwBytesWritten, NULL); 514 if(ret == FALSE || dwBytesWritten != dwSize) { 515 DebugInt3(); 516 goto failure; 517 } 518 CloseHandle(hFile); 519 520 if(lpCopy) free(lpCopy); 521 522 SetLastError(ERROR_SUCCESS); 523 return TRUE; 524 525 failure: 526 if(hFile != INVALID_HANDLE_VALUE) { 527 CloseHandle(hFile); 528 DeleteFileA(lpszFontRes); 529 } 530 if(lpCopy) free(lpCopy); 531 SetLastError(ERROR_INVALID_PARAMETER); //not correct 168 532 return FALSE; 169 533 } … … 200 564 return CreateScalableFontResourceA(fdwHidden, lpszFontResA, lpszFontFileA, lpszCurrentPathA); 201 565 } 202 203 566 //****************************************************************************** 567 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.