Ignore:
Timestamp:
Jun 18, 2009, 12:12:33 PM (16 years ago)
Author:
ydario
Message:

Gdi32 updates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gdi32/fontres.cpp

    r10373 r21304  
    2626#include <dbglog.h>
    2727#include <unicode.h>
    28 #include <stats.h>
     28#include <heapstring.h>
     29#include <neexe.h>
    2930#include <objhandle.h>
     31#include <font.h>
     32#include <vmutex.h>
     33#include "ft2supp.h"
     34
    3035#include "oslibgpi.h"
    3136
     
    4853
    4954static SCALABLEFONTS    *publicfonts = NULL;
    50 static CRITICAL_SECTION  fntcritsect = {0};
    51 
    52 #define FntLock()       EnterCriticalSection(&fntcritsect)
    53 #define FntUnlock()     LeaveCriticalSection(&fntcritsect)
     55static VMutex fntmutex;
     56
     57#define FntLock()       fntmutex.enter()
     58#define FntUnlock()     fntmutex.leave()
    5459
    5560
     
    8590//******************************************************************************
    8691//******************************************************************************
     92static 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
     132failure:
     133    if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
     134    if(lpFileData) free(lpFileData);
     135    return NULL;
     136}
     137//******************************************************************************
     138//******************************************************************************
    87139DWORD WIN32API GetFontData(HDC hdc, DWORD dwTable,
    88140                           DWORD dwOffset,
    89141                           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)
    94174
    95175  return(GDI_ERROR);
    96176}
    97177//******************************************************************************
     178//TODO: supposed to support more than only .fon files
    98179//******************************************************************************
    99180int WIN32API AddFontResourceA(LPCSTR szFont)
    100181{
    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];
    102192
    103193    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);
    110298    return 1;
     299
     300failure:
     301    if(pDosHdr) free(pDosHdr);
     302    if(newname) free(newname);
     303    return 0;
    111304}
    112305//******************************************************************************
     
    115308{
    116309 char *astring = UnicodeToAsciiString((LPWSTR)szFont);
    117  BOOL  rc;
     310    int  ret;
    118311
    119312    dprintf(("GDI32: AddFontResourceW"));
    120     // NOTE: This will not work as is (needs UNICODE support)
    121     rc = AddFontResourceA(astring);
     313    ret = AddFontResourceA(astring);
    122314    FreeAsciiString(astring);
    123     return rc;
     315    return ret;
    124316}
    125317//******************************************************************************
     
    127319BOOL WIN32API RemoveFontResourceA(LPCSTR lpszFont)
    128320{
     321    BOOL ret;
     322
    129323    dprintf(("GDI32: RemoveFontResourceA %s", lpszFont));
     324   
     325    if(!publicfonts) {
     326        dprintf(("WARNING: font not found in our list!!"));
    130327    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;
    131350}
    132351//******************************************************************************
     
    135354{
    136355 char *astring = UnicodeToAsciiString((LPWSTR)szFont);
    137  BOOL  rc;
     356    BOOL  ret;
    138357
    139358    dprintf(("GDI32: RemoveFontResourceW"));
    140     rc = RemoveFontResourceA(astring);
     359    ret = RemoveFontResourceA(astring);
    141360    FreeAsciiString(astring);
    142     return(rc);
     361    return ret;
    143362}
    144363/*****************************************************************************
     
    163382                                          LPCSTR lpszCurrentPath)
    164383{
    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
     525failure:
     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
    168532  return FALSE;
    169533}
     
    200564  return CreateScalableFontResourceA(fdwHidden, lpszFontResA, lpszFontFileA, lpszCurrentPathA);
    201565}
    202 
    203 
     566//******************************************************************************
     567//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.