Index: trunk/src/gdi32/devcontext.cpp
===================================================================
--- trunk/src/gdi32/devcontext.cpp	(revision 21303)
+++ trunk/src/gdi32/devcontext.cpp	(revision 21304)
@@ -56,4 +56,16 @@
 static BOOL GetPMQueueName(LPSTR pDeviceName, LPSTR lpszPMQueue, INT cbPMQueue)
 {
+    static HINSTANCE                hInstance = 0;
+    static PFN_SPLQUERYPMQUEUENAME  pfnSplQueryPMQueueName = NULL;
+
+    if(hInstance == 0) hInstance = LoadLibraryA("WINSPOOL.DRV");
+
+    if(hInstance) {
+        pfnSplQueryPMQueueName = (PFN_SPLQUERYPMQUEUENAME)GetProcAddress(hInstance, "SplQueryPMQueueName");
+        if(pfnSplQueryPMQueueName) {
+            return pfnSplQueryPMQueueName(pDeviceName, lpszPMQueue, cbPMQueue);
+        }
+    }
+    DebugInt3();
     return FALSE;
 }
Index: trunk/src/gdi32/dibitmap.cpp
===================================================================
--- trunk/src/gdi32/dibitmap.cpp	(revision 21303)
+++ trunk/src/gdi32/dibitmap.cpp	(revision 21304)
@@ -183,4 +183,6 @@
     pDCData pHps;
 
+    dprintf(("GDI32: CreateCompatibleBitmap. HDC = %08x, w:%d, h:%d",hdc, nWidth, nHeight));
+
     pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
     if(!pHps)
Index: trunk/src/gdi32/fontres.cpp
===================================================================
--- trunk/src/gdi32/fontres.cpp	(revision 21303)
+++ trunk/src/gdi32/fontres.cpp	(revision 21304)
@@ -26,6 +26,11 @@
 #include <dbglog.h>
 #include <unicode.h>
-#include <stats.h>
+#include <heapstring.h>
+#include <neexe.h>
 #include <objhandle.h>
+#include <font.h>
+#include <vmutex.h>
+#include "ft2supp.h"
+
 #include "oslibgpi.h"
 
@@ -48,8 +53,8 @@
 
 static SCALABLEFONTS    *publicfonts = NULL;
-static CRITICAL_SECTION  fntcritsect = {0};
-
-#define FntLock()	EnterCriticalSection(&fntcritsect)
-#define FntUnlock()     LeaveCriticalSection(&fntcritsect)
+static VMutex fntmutex;
+
+#define FntLock()	fntmutex.enter()
+#define FntUnlock()     fntmutex.leave()
 
 
@@ -85,28 +90,216 @@
 //******************************************************************************
 //******************************************************************************
+static LPVOID ReadEntireFile(LPSTR lpszFileName, DWORD *lpdwSize = NULL)
+{
+    HFILE hFile = INVALID_HANDLE_VALUE;
+
+    DWORD dwSize, dwBytesRead, ret;
+    LPVOID lpFileData = NULL;
+
+    hFile = CreateFileA(lpszFileName,
+                        GENERIC_READ,      
+                        FILE_SHARE_READ | FILE_SHARE_WRITE,
+                        NULL,                              
+                        OPEN_EXISTING,
+                        0, 
+                        NULL);                             
+
+    if(hFile == INVALID_HANDLE_VALUE) {
+        DebugInt3();
+        goto failure;
+    }  
+    //determine filesize
+    dwSize = SetFilePointer(hFile, 0, NULL, FILE_END);
+    SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
+
+    //allocate memory to hold the entire file
+    lpFileData = (char *)malloc(dwSize);
+    if(lpFileData == NULL) {
+        DebugInt3();
+        goto failure; 
+    }
+    //and read it
+    ret = ReadFile(hFile, lpFileData, dwSize, &dwBytesRead, NULL);
+    if(ret == FALSE || dwBytesRead != dwSize) {
+        DebugInt3();
+        goto failure;
+    }
+    if(lpdwSize) *lpdwSize = dwSize;
+
+    CloseHandle(hFile);
+    return lpFileData;
+
+failure:
+    if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
+    if(lpFileData) free(lpFileData);
+    return NULL;
+}
+//******************************************************************************
+//******************************************************************************
 DWORD WIN32API GetFontData(HDC hdc, DWORD dwTable,
                            DWORD dwOffset,
                            LPVOID lpvBuffer,
-                           DWORD dbData)
-{
-  dprintf(("GDI32: GetFontData, not implemented (GDI_ERROR)\n"));
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+                           DWORD cbData)
+{
+    HFONT hFont;
+    SCALABLEFONTS *font;
+
+    dprintf(("GDI32: GetFontData, partially implemented"));
+
+    hFont = GetCurrentObject(hdc, OBJ_FONT);
+    if(hFont == 0) {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return GDI_ERROR;
+    }
+    font = (SCALABLEFONTS *)ObjQueryHandleGDI32Data(hFont, HNDL_FONT);
+    if(font == NULL) {
+        return FT2Module.Ft2GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
+    }
+
+    if(font->pFontData == NULL) 
+    {
+        font->pFontData = (char *)ReadEntireFile(font->szFileName, &font->dwFontSize);
+        if(!font->pFontData) return GDI_ERROR;
+    }
+
+    cbData = min(cbData, font->dwFontSize);
+    if(dwTable == 0 && dwOffset == 0) {
+        if(lpvBuffer == NULL) return font->dwFontSize;
+
+        memcpy(lpvBuffer, font->pFontData, cbData);
+        return cbData;
+    }
+
+    //todo: parse TTF structure (haven't seen anybody rely on that yet)
 
   return(GDI_ERROR);
 }
 //******************************************************************************
+//TODO: supposed to support more than only .fon files
 //******************************************************************************
 int WIN32API AddFontResourceA(LPCSTR szFont)
 {
-    HINSTANCE hInstance;
+    DWORD   ret, alignment, nrFonts, fontOrdinal, i;
+    PIMAGE_DOS_HEADER pDosHdr = NULL;
+    PIMAGE_OS2_HEADER pNEHdr;
+    struct resource_typeinfo_s *pResInfo;
+    struct resource_nameinfo_s *pNameInfo;
+    LPFONTDIR16 pFontDir = NULL;
+    char  *pFontNameId;
+    char  *pResNameTable;
+    char  *pFontPath, *newname = NULL, *extension;
+    char   szFamily[32], szFace[32];
 
     dprintf(("GDI32: AddFontResourceA %s", szFont));
-    hInstance = LoadLibraryA(szFont);
-    if(hInstance) {
-        dprintf(("AddFontResourceA: executable file; NOT IMPLEMENTED"));
-        FreeLibrary(hInstance);
-        return 1;
-    }
+
+    if(GetFileAttributesA(szFont) == -1) {
+        dprintf(("WARNING: Font res file doesn't exists"));
+        SetLastError(ERROR_INVALID_PARAMETER); 
+        return FALSE;
+    }
+
+    //Support for raw .ttf files as well
+    newname = strupr(strdup(szFont));
+    extension = strrchr(newname, '.');
+    if (!strcmp(extension, ".TTF"))
+    {    
+	    //get font family and face names
+	    OSLibGpiQueryFontName(newname, szFamily, szFace, sizeof(szFamily));
+    }
+    else
+    {
+	    pDosHdr = (PIMAGE_DOS_HEADER)ReadEntireFile((LPSTR)szFont);
+	    if(!pDosHdr) return FALSE;
+   
+	    pNEHdr  = (PIMAGE_OS2_HEADER) ((char *)pDosHdr + pDosHdr->e_lfanew);
+	    if(pDosHdr->e_magic != IMAGE_DOS_SIGNATURE || 
+	       pNEHdr->ne_magic != IMAGE_OS2_SIGNATURE) {
+	        dprintf(("Unknown file format"));
+	        goto failure;
+    }
+
+	    pResInfo = (struct resource_typeinfo_s *)((char *)pNEHdr + pNEHdr->ne_rsrctab);
+	    alignment = *(WORD *)pResInfo;
+	    pResInfo = (struct resource_typeinfo_s *)((char *)pResInfo+sizeof(WORD));
+
+	    //first resource is a font directory
+	    if(pResInfo->type_id != NE_RSCTYPE_FONTDIR && pResInfo->count != 1) {
+	        dprintf(("Unknown file format"));
+	        goto failure;
+	    }
+	    pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1);
+	    pFontDir    = (LPFONTDIR16)((char *)pDosHdr + (pNameInfo->offset << alignment));
+	    //first word = length followed by the string (not terminated)
+	    pFontNameId = (char *)pResInfo - sizeof(WORD) + pNameInfo->id;
+	
+	    nrFonts     = *(WORD *)pFontDir;
+	    fontOrdinal = *((WORD *)pFontDir+1);
+	    pFontDir    = (LPFONTDIR16)((char *)pFontDir + 2*sizeof(WORD));
+
+	    pResNameTable = (char *)pNEHdr + pNEHdr->ne_restab;
+
+	    //second resource is the absolute path of the TTF file
+	    pResInfo  = (struct resource_typeinfo_s *)(pNameInfo+1);
+	    if(pResInfo->type_id != 0x80CC && pResInfo->count != 1) {
+        	dprintf(("Unknown file format"));
+	        goto failure;
+	    }
+	    pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1);
+	    pFontPath = ((char *)pDosHdr + (pNameInfo->offset << alignment));
+
+            free(newname);
+   
+	    //GPI makes assumptions about the file based on the extention (d'oh)
+	    newname = strdup(pFontPath);
+	    extension = strrchr(newname, '.');
+    
+	    strcpy(extension, ".TTF");
+	    CopyFileA(pFontPath, newname, FALSE);
+    }
+         	
+    //Load the TrueType font
+    ret = OSLibGpiLoadFonts(newname);
+    if(ret == FALSE) {
+        dprintf(("OSLibGpiLoadFonts %s failed!!", pFontPath));
+        goto failure;
+    }
+
+    //add to the list of known public fonts that we added before
+    if(publicfonts == NULL) {
+        publicfonts = (SCALABLEFONTS*)malloc(MAX_PUBLICFONTS*sizeof(SCALABLEFONTS));
+        if(publicfonts == NULL) {
+            DebugInt3();
+            goto failure;
+        }
+        memset(publicfonts, 0, MAX_PUBLICFONTS*sizeof(SCALABLEFONTS));
+    }
+    FntLock();
+    for(i=0;i<MAX_PUBLICFONTS;i++) {
+        if(publicfonts[i].szFaceName[0] == 0) {
+            break;
+        }
+    }
+    if(i == MAX_PUBLICFONTS) {
+        FntUnlock();
+        DebugInt3();
+        goto failure;
+    }
+    strncpy(publicfonts[i].szFileName, newname, sizeof(publicfonts[i].szFileName));
+    if (pFontDir)
+      strncpy(publicfonts[i].szFaceName, pFontDir->szDeviceName, sizeof(publicfonts[i].szFaceName));
+    else
+      strncpy(publicfonts[i].szFaceName, szFace, sizeof(publicfonts[i].szFaceName));
+    strncpy(publicfonts[i].szFontResName, szFont, sizeof(publicfonts[i].szFontResName));
+    publicfonts[i].pFontData = NULL;
+    FntUnlock();
+
+    free(newname);
+    free(pDosHdr);
     return 1;
+
+failure:
+    if(pDosHdr) free(pDosHdr);
+    if(newname) free(newname);
+    return 0;
 }
 //******************************************************************************
@@ -115,11 +308,10 @@
 {
  char *astring = UnicodeToAsciiString((LPWSTR)szFont);
- BOOL  rc;
+    int  ret;
 
     dprintf(("GDI32: AddFontResourceW"));
-    // NOTE: This will not work as is (needs UNICODE support)
-    rc = AddFontResourceA(astring);
+    ret = AddFontResourceA(astring);
     FreeAsciiString(astring);
-    return rc;
+    return ret;
 }
 //******************************************************************************
@@ -127,6 +319,33 @@
 BOOL WIN32API RemoveFontResourceA(LPCSTR lpszFont)
 {
+    BOOL ret;
+
     dprintf(("GDI32: RemoveFontResourceA %s", lpszFont));
+    
+    if(!publicfonts) {
+        dprintf(("WARNING: font not found in our list!!"));
     return FALSE;
+    }
+    FntLock();
+    for(int i=0;i<MAX_PUBLICFONTS;i++) {
+        if(strcmp(publicfonts[i].szFontResName, lpszFont) == 0)  
+        {
+            ret = OSLibGpiUnloadFonts(publicfonts[i].szFileName);
+            DeleteFileA(publicfonts[i].szFileName);
+
+            if(publicfonts[i].pFontData) free(publicfonts[i].pFontData);
+            publicfonts[i].pFontData     = 0;
+            publicfonts[i].szFileName[0] = 0;
+            publicfonts[i].szFaceName[0] = 0;
+            break;
+        }
+    }
+    FntUnlock();
+    if(i == MAX_PUBLICFONTS) {
+        dprintf(("WARNING: font not found in our list!!"));
+// no need to trap on a warning        DebugInt3();
+        return FALSE;
+    }
+    return ret;
 }
 //******************************************************************************
@@ -135,10 +354,10 @@
 {
  char *astring = UnicodeToAsciiString((LPWSTR)szFont);
- BOOL  rc;
+    BOOL  ret;
 
     dprintf(("GDI32: RemoveFontResourceW"));
-    rc = RemoveFontResourceA(astring);
+    ret = RemoveFontResourceA(astring);
     FreeAsciiString(astring);
-    return(rc);
+    return ret;
 }
 /*****************************************************************************
@@ -163,7 +382,152 @@
                                           LPCSTR lpszCurrentPath)
 {
-  dprintf(("GDI32: CreateScalableFontResourceA %x %s %s %s not implemented", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath));
-
-//  return OSLibGpiLoadFonts((LPSTR)lpszFontFile);
+    HRSRC   hRsrc;
+    HINSTANCE hGdi32;
+    HGLOBAL handle;
+    DWORD   dwSize;
+    LPVOID  lpData, lpCopy = NULL;
+    HANDLE  hFile = 0;
+    DWORD   ret, dwBytesWritten, alignment, nrFonts, fontOrdinal, len;
+    PIMAGE_DOS_HEADER pDosHdr;
+    PIMAGE_OS2_HEADER pNEHdr;
+    struct resource_typeinfo_s *pResInfo;
+    struct resource_nameinfo_s *pNameInfo;
+    LPFONTDIR16 pFontDir;
+    char  *pFontNameId;
+    char  *pResNameTable;
+    char  *pFontPath, *newname, *extension;
+    char   szFamily[32], szFace[32];
+
+    dprintf(("GDI32: CreateScalableFontResourceA %x %s %s %s partly implemented", fdwHidden, lpszFontRes, lpszFontFile, lpszCurrentPath));
+
+    if(lpszCurrentPath != NULL) {
+        //figure out which possibilities exist
+        DebugInt3();
+        return FALSE;
+    }
+
+    //This function is supposed to create a font resource file (.fot; NE dll with
+    //references to the TTF file (absolute path))
+
+    if(GetFileAttributesA(lpszFontRes) != -1) {
+        dprintf(("WARNING: Font res file already exists"));
+        SetLastError(ERROR_INVALID_PARAMETER); 
+        return FALSE;
+    }
+
+    //fetch our font resource file example
+    hGdi32 = GetModuleHandleA("GDI32");
+    hRsrc = FindResourceA( hGdi32, TESTFONT_RESNAME, RT_RCDATAA );
+    if(!hRsrc) {
+        dprintf(("WARNING: Test font file resource not found!!"));
+        DebugInt3();
+        return FALSE;
+    }
+    handle = LoadResource(hGdi32, hRsrc);
+    dwSize = SizeofResource(hGdi32, hRsrc);
+    lpData = LockResource(handle);
+    if(!dwSize || !handle || !lpData) {
+        dprintf(("WARNING: Test font file resource not loaded/locked!!"));
+        DebugInt3();
+        return FALSE;
+    }
+    lpCopy = malloc(dwSize);
+    if(lpCopy == NULL) {
+        DebugInt3();
+        return FALSE;
+    }
+    memcpy(lpCopy, lpData, dwSize);
+
+    pDosHdr = (PIMAGE_DOS_HEADER)lpCopy;
+    pNEHdr  = (PIMAGE_OS2_HEADER) ((char *)pDosHdr + pDosHdr->e_lfanew);
+    if(pDosHdr->e_magic != IMAGE_DOS_SIGNATURE || 
+       pNEHdr->ne_magic != IMAGE_OS2_SIGNATURE) {
+        dprintf(("Unknown file format"));
+        goto failure;
+    }
+
+    pResInfo = (struct resource_typeinfo_s *)((char *)pNEHdr + pNEHdr->ne_rsrctab);
+    alignment = *(WORD *)pResInfo;
+    pResInfo = (struct resource_typeinfo_s *)((char *)pResInfo+sizeof(WORD));
+
+    //first resource is a font directory
+    if(pResInfo->type_id != NE_RSCTYPE_FONTDIR && pResInfo->count != 1) {
+        dprintf(("Unknown file format"));
+        goto failure;
+    }
+    pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1);
+    pFontDir    = (LPFONTDIR16)((char *)pDosHdr + (pNameInfo->offset << alignment));
+    //first word = length followed by the string (not terminated)
+    pFontNameId = (char *)pResInfo - sizeof(WORD) + pNameInfo->id;
+
+    //GPI makes assumptions about the file based on the extention (d'oh)
+    newname = strdup(lpszFontFile);
+    extension = strrchr(newname, '.');
+    
+    strcpy(extension, ".TTF");
+    CopyFileA(lpszFontFile, newname, FALSE);
+
+    //get font family and face names
+    OSLibGpiQueryFontName(newname, szFamily, szFace, sizeof(szFamily));
+
+    DeleteFileA(newname);
+    free(newname);
+
+    nrFonts     = *(WORD *)pFontDir;
+    fontOrdinal = *((WORD *)pFontDir+1);
+    pFontDir    = (LPFONTDIR16)((char *)pFontDir + 2*sizeof(WORD));
+
+    //copy family and face names to fontdir structure
+    len = strlen(szFamily);
+    strcpy(pFontDir->szDeviceName, szFamily);
+    strcpy(pFontDir->szDeviceName + len + 1, szFace);
+
+    dprintf(("Family %s, Face %s", szFamily, szFace));
+
+    pResNameTable = (char *)pNEHdr + pNEHdr->ne_restab;
+
+    //second resource is the absolute path of the TTF file
+    pResInfo  = (struct resource_typeinfo_s *)(pNameInfo+1);
+    if(pResInfo->type_id != 0x80CC && pResInfo->count != 1) {
+        dprintf(("Unknown file format"));
+        goto failure;
+    }
+    pNameInfo = (struct resource_nameinfo_s *)(pResInfo+1);
+    pFontPath = ((char *)pDosHdr + (pNameInfo->offset << alignment));
+    //overwrite absolute font path
+    strcpy(pFontPath, lpszFontFile);
+    pNameInfo->length = strlen(lpszFontFile)+1;
+
+    hFile = CreateFileA(lpszFontRes,                      
+                        GENERIC_READ | GENERIC_WRITE,      
+                        FILE_SHARE_READ | FILE_SHARE_WRITE,
+                        NULL,                              
+                        CREATE_NEW,
+                        0, 
+                        NULL);                             
+
+    if(hFile == INVALID_HANDLE_VALUE) {
+        DebugInt3();
+        goto failure;
+    }  
+    ret = WriteFile(hFile, lpCopy, dwSize, &dwBytesWritten, NULL);
+    if(ret == FALSE || dwBytesWritten != dwSize) {
+        DebugInt3();
+        goto failure;
+    }    
+    CloseHandle(hFile);
+
+    if(lpCopy) free(lpCopy);
+
+    SetLastError(ERROR_SUCCESS);
+    return TRUE;
+
+failure:
+    if(hFile != INVALID_HANDLE_VALUE) {
+        CloseHandle(hFile);
+        DeleteFileA(lpszFontRes);
+    }
+    if(lpCopy) free(lpCopy);
+    SetLastError(ERROR_INVALID_PARAMETER); //not correct
   return FALSE;
 }
@@ -200,4 +564,4 @@
   return CreateScalableFontResourceA(fdwHidden, lpszFontResA, lpszFontFileA, lpszCurrentPathA);
 }
-
-
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/gdi32/ft2supp.cpp
===================================================================
--- trunk/src/gdi32/ft2supp.cpp	(revision 21303)
+++ trunk/src/gdi32/ft2supp.cpp	(revision 21304)
@@ -96,4 +96,7 @@
        else pfnFt2EnableFontEngine(bEnabled);
 
+       pfnGetGlyphIndices = (PFN_FT2GETGLYPHINDICES)QueryProcAddress("Ft2GetGlyphIndices");
+       if(!pfnGetGlyphIndices) dprintf(("Ft2GetGlyphIndices not found!!"));
+
        pfnFt2GetTextExtentW  = (PFN_FT2GETTEXTEXTENTW)QueryProcAddress("Ft2GetTextExtentW");
        if(!pfnFt2GetTextExtentW) dprintf(("Ft2GetTextExtentW not found!!"));
@@ -104,4 +107,10 @@
        if(!pfnFt2CharStringPosAtW) dprintf(("Ft2CharStringPosAtW not found!!"));
 
+       pfnFt2GetGlyphOutline = (PFN_FT2GETGLYPHOUTLINE)QueryProcAddress("Ft2GetGlyphOutline");
+       if(!pfnFt2GetGlyphOutline) dprintf(("Ft2GetGlyphOutline not found!!"));
+
+       pfnFt2GetFontData = (PFN_FT2GETFONTDATA)QueryProcAddress("Ft2GetFontData");
+       if(!pfnFt2GetFontData) dprintf(("Ft2GetFontData not found!!"));
+
        pfnFt2QueryFontType = (PFN_FT2QUERYFONTTYPE)QueryProcAddress("Ft2QueryFontType");
        if(!pfnFt2QueryFontType) dprintf(("Ft2QueryFontType not found!!"));
@@ -109,4 +118,7 @@
        pfnFt2QueryStringWidthW = (PFN_FT2QUERYSTRINGWIDTHW)QueryProcAddress("Ft2QueryStringWidthW");
        if(!pfnFt2QueryStringWidthW) dprintf(("Ft2QueryStringWidthW not found!!"));
+
+       pfnFt2GetCharacterPlacementW = (PFN_FT2GETCHARACTERPLACEMENTW)QueryProcAddress("Ft2GetCharacterPlacementW");
+       if(!pfnFt2GetCharacterPlacementW) dprintf(("pfnFt2GetCharacterPlacementW not found!!"));
 
        // Do not register functions for Mozilla plugins
@@ -187,4 +199,14 @@
 DWORD CFT2Module::Ft2GetGlyphIndices(HPS hps, LPCWSTR str, int c, LPWORD pgi, DWORD fl)
 {
+    DWORD  ret; 
+    USHORT sel;
+
+    // All FreeType calls should be wrapped for saving FS 
+    if(pfnGetGlyphIndices) {
+        sel  = RestoreOS2FS();
+        ret  = pfnGetGlyphIndices(hps, (WCHAR*)str, c, (ULONG*)pgi, fl);
+        SetFS(sel);
+        return ret; 
+    }
     //no fallback
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED_W);
@@ -195,4 +217,16 @@
 DWORD CFT2Module::Ft2GetGlyphOutline(HPS hps, UINT glyph, UINT format, LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf, const MAT2* lpmat)
 {
+    DWORD  ret; 
+    USHORT sel;
+
+    // All FreeType calls should be wrapped for saving FS 
+    if (pfnFt2GetGlyphOutline)
+    {
+        sel  = RestoreOS2FS();
+        ret  = pfnFt2GetGlyphOutline (hps, glyph, format, lpgm, buflen, buf, lpmat);
+        SetFS(sel);
+        return ret; 
+    }
+    
     //no fallback
     SetLastError(ERROR_INVALID_FUNCTION_W);
@@ -353,4 +387,15 @@
                                  LPVOID lpvBuffer, DWORD cbData)
 {
+    DWORD  ret; 
+    USHORT sel;
+
+    // All FreeType calls should be wrapped for saving FS 
+    if(pfnFt2GetFontData) {
+        sel  = RestoreOS2FS();
+        ret  = pfnFt2GetFontData(hps, dwTable, dwOffset, lpvBuffer, cbData);
+        SetFS(sel);
+        if(ret || (ret == GDI_ERROR && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
+            return ret; 
+    }
     //no fallback
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED_W);
@@ -501,4 +546,42 @@
             lpResults->lpOrder[i] = i;
 
+    // All FreeType calls should be wrapped for saving FS 
+    if(pfnFt2GetCharacterPlacementW) {
+        sel  = RestoreOS2FS();
+        ret  = pfnFt2GetCharacterPlacementW((HPS)hdc, lpString, nSet, nMaxExtent, lpResults, dwFlags);
+        SetFS(sel);
+        if(ret || (ret == 0 && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
+        {
+#ifdef DEBUG
+           if(ret && lpResults->lpDx) {
+               for (i = 0; i < nSet; i++)
+               {
+                   dprintf(("%c pWidthArray[%d] = %d", lpString[i], i, lpResults->lpDx[i]));
+               }
+           }
+#endif
+           if(pHps && pHps->isPrinter && pHps->hdc)
+           {//scale for printer dcs
+               LONG alArray[2];
+
+               if(OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0]) &&
+                  alArray[0] != alArray[1]) 
+               {
+                   dprintf(("Different hor/vert resolutions (%d,%d)", alArray[0], alArray[1]));
+                   if(lpResults->lpDx) {
+                       for (i = 0; i < nSet; i++)
+                       {
+                           lpResults->lpDx[i] = lpResults->lpDx[i] * alArray[0] / alArray[1];
+                       }
+                   }
+                   ULONG x = (ret & 0xffff);
+                   x = x * alArray[0] / alArray[1];
+                   ret &= ~0xffff;
+                   ret |= (x & 0xffff);
+               }
+           }
+           return ret; 
+        }
+    }
     //fallback method
 
Index: trunk/src/gdi32/ft2supp.h
===================================================================
--- trunk/src/gdi32/ft2supp.h	(revision 21303)
+++ trunk/src/gdi32/ft2supp.h	(revision 21304)
@@ -15,4 +15,5 @@
 #include <winconst.h>
 #include <win32type.h>
+#include <ft2lib.h>
 
 #ifndef GDI_ERROR
@@ -25,5 +26,5 @@
 #define FT2LIBNAME 		"ft2lib.dll"
 #define FT2LIB_MAJOR_VERSION	2
-#define FT2LIB_MINOR_VERSION    1
+#define FT2LIB_MINOR_VERSION    3
 
 // Add here function pointer typedefs to funcs that we will use
@@ -50,9 +51,4 @@
 
 typedef VOID  (* SYSTEM PFN_FT2GETVERSION)(LONG *plMajor, LONG *plMinor, LONG *plBuildNumber);
-
-#define FT2_FONTTYPE_UNKNOWN	0
-#define FT2_FONTTYPE_TRUETYPE	1
-#define FT2_FONTTYPE_TYPE1	2
-#define FT2_FONTTYPE_BITMAP	3
 
 class CFT2Module {
Index: trunk/src/gdi32/gdistats.cpp
===================================================================
--- trunk/src/gdi32/gdistats.cpp	(revision 21303)
+++ trunk/src/gdi32/gdistats.cpp	(revision 21304)
@@ -13,4 +13,267 @@
 #include <objhandle.h>
 
+#ifdef RAS
+
+RAS_TRACK_HANDLE rthFont;
+RAS_TRACK_HANDLE rthDC;
+RAS_TRACK_HANDLE rthPen;
+RAS_TRACK_HANDLE rthBrush;
+RAS_TRACK_HANDLE rthRgn;
+RAS_TRACK_HANDLE rthBmp;
+
+void STATS_CreateFontIndirect(HFONT hFont, LOGFONTA* lplf)
+{
+    if (!rthFont) STATS_InitializeGDI32 ();
+    RasAddObject (rthFont, hFont, lplf, sizeof (LOGFONTA));
+}
+void STATS_DeleteFont(HFONT hFont)
+{
+    RasRemoveObject (rthFont, hFont);
+}
+void STATS_CreateCompatibleDC(HDC hdc, HDC hdcCreated)
+{
+    if (!rthDC) STATS_InitializeGDI32 ();
+    RasAddObject (rthDC, hdcCreated, &hdc, sizeof (hdc));
+}
+void STATS_CreateICA(HDC hdc, LPCSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszOutput,
+                     const DEVMODEA *lpdvmInit)
+{
+    if (!rthDC) STATS_InitializeGDI32 ();
+    RasAddObject (rthDC, hdc, NULL, 0);
+}
+void STATS_CreateDCA(HDC hdc, LPCSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszOutput,
+                     const DEVMODEA *lpdvmInit)
+{
+    if (!rthDC) STATS_InitializeGDI32 ();
+    RasAddObject (rthDC, hdc, NULL, 0);
+}
+void STATS_DeleteDC(HDC hdc)
+{
+    RasRemoveObject (rthDC, hdc);
+}
+void STATS_CreatePatternBrush(HBRUSH hBrush, HBITMAP hBitmap)
+{
+    if (!rthBrush) STATS_InitializeGDI32 ();
+    RasAddObject (rthBrush, hBrush, &hBitmap, sizeof (hBitmap));
+}
+void STATS_CreateDIBPatternBrushPt(HBRUSH hBrush, LPCVOID buffer, DWORD usage)
+{
+    if (!rthBrush) STATS_InitializeGDI32 ();
+    RasAddObject (rthBrush, hBrush, &buffer, sizeof (buffer));
+}
+void STATS_CreateBrushIndirect(HBRUSH hBrush, LPLOGBRUSH pLogBrush)
+{
+    if (!rthBrush) STATS_InitializeGDI32 ();
+    RasAddObject (rthBrush, hBrush, pLogBrush, sizeof (LOGBRUSH));
+}
+void STATS_CreateHatchBrush(HBRUSH hBrush, int fnStyle, COLORREF clrref)
+{
+    struct Parms
+    {
+        int fnStyle; 
+        COLORREF clrref;
+    } parms = {fnStyle, clrref};
+    if (!rthBrush) STATS_InitializeGDI32 ();
+    RasAddObject (rthBrush, hBrush, &parms, sizeof (parms));
+}
+void STATS_CreateSolidBrush(HBRUSH hBrush, COLORREF color)
+{
+    if (!rthBrush) STATS_InitializeGDI32 ();
+    RasAddObject (rthBrush, hBrush, &color, sizeof (COLORREF));
+}
+void STATS_DeleteBrush(HBRUSH hBrush)
+{
+    RasRemoveObject (rthBrush, hBrush);
+}
+void STATS_CreatePenIndirect(HPEN hPen, const LOGPEN *lplgpn)
+{
+    if (!rthPen) STATS_InitializeGDI32 ();
+    RasAddObject (rthPen, hPen, (void *)lplgpn, sizeof (LOGPEN));
+}
+void STATS_CreatePen(HPEN hPen, int fnPenStyle, int nWidth, COLORREF crColor)
+{
+    struct Parms
+    {
+        int fnPenStyle;
+        int nWidth; 
+        COLORREF crColor;
+    } parms = {fnPenStyle, nWidth, crColor};
+    
+    if (!rthPen) STATS_InitializeGDI32 ();
+    RasAddObject (rthPen, hPen, &parms, sizeof (parms));
+}
+void STATS_ExtCreatePen(HPEN hPen, DWORD dwPenStyle, DWORD dwWidth, const LOGBRUSH *lplb, 
+                        DWORD dwStyleCount, const DWORD *lpStyle)
+{
+    struct Parms
+    {
+        DWORD dwPenStyle; 
+        DWORD dwWidth; 
+        const LOGBRUSH *lplb;
+        DWORD dwStyleCount; 
+        const DWORD *lpStyle;
+    } parms = {dwPenStyle, dwWidth, lplb, 
+               dwStyleCount, lpStyle};
+    
+    if (!rthPen) STATS_InitializeGDI32 ();
+    RasAddObject (rthPen, hPen, &parms, sizeof (parms));
+}
+void STATS_DeletePen(HPEN hPen)
+{
+    RasRemoveObject (rthPen, hPen);
+}
+
+void STATS_CreatePolyPolygonRgn(HRGN hRgn, const POINT *lppt, const int *pPolyCount, int nCount, int fnPolyFillMode)
+{
+    if (!rthRgn) STATS_InitializeGDI32 ();
+    RasAddObject (rthRgn, hRgn, NULL, 0);
+}
+void STATS_CreateRectRgn(HRGN hRgn, int left, int top, int right, int bottom)
+{
+    if (!rthRgn) STATS_InitializeGDI32 ();
+    RasAddObject (rthRgn, hRgn, NULL, 0);
+}
+void STATS_CreateRoundRectRgn(HRGN hRgn, int left, int top, int right, int bottom, int nWidthEllipse, int nHeightEllipse)
+{
+    if (!rthRgn) STATS_InitializeGDI32 ();
+    RasAddObject (rthRgn, hRgn, NULL, 0);
+}
+void STATS_ExtCreateRegion(HRGN hRgn, PVOID pXform, DWORD count, const RGNDATA * pData)
+{
+    if (!rthRgn) STATS_InitializeGDI32 ();
+    RasAddObject (rthRgn, hRgn, NULL, 0);
+}
+void STATS_CreateEllipticRgn(HRGN hRgn, int left, int top, int right, int bottom)
+{
+    if (!rthRgn) STATS_InitializeGDI32 ();
+    RasAddObject (rthRgn, hRgn, NULL, 0);
+}
+void STATS_CreatePolygonRgn(HRGN hRgn, const POINT * lppt, int cPoints, int fnPolyFillMode)
+{
+    if (!rthRgn) STATS_InitializeGDI32 ();
+    RasAddObject (rthRgn, hRgn, NULL, 0);
+}
+void STATS_DeleteRgn(HRGN hRgn)
+{
+    RasRemoveObject (rthRgn, hRgn);
+}
+
+void STATS_CreateDIBitmap(HBITMAP hBitmap,HDC hdc, const BITMAPINFOHEADER *lpbmih,
+                          DWORD fdwInit, const void *lpbInit,
+                          const BITMAPINFO *lpbmi, UINT fuUsage)
+{
+    if (!rthBmp) STATS_InitializeGDI32 ();
+    RasAddObject (rthBmp, hBitmap, NULL, 0);
+}
+void STATS_CreateCompatibleBitmap(HBITMAP hBitmap,HDC hdc, int nWidth, int nHeight)
+{
+    if (!rthBmp) STATS_InitializeGDI32 ();
+    RasAddObject (rthBmp, hBitmap, NULL, 0);
+}
+void STATS_CreateBitmap(HBITMAP hBitmap,int nWidth, int nHeight, UINT cPlanes,
+                        UINT cBitsPerPel, const void *lpvBits)
+{
+    if (!rthBmp) STATS_InitializeGDI32 ();
+    RasAddObject (rthBmp, hBitmap, NULL, 0);
+}
+void STATS_CreateDIBSection(HBITMAP hBitmap,HDC hdc, BITMAPINFO *pbmi, UINT iUsage,
+                            VOID **ppvBits, HANDLE hSection, DWORD dwOffset)
+{
+    if (!rthBmp) STATS_InitializeGDI32 ();
+    RasAddObject (rthBmp, hBitmap, NULL, 0);
+}
+void STATS_CreateBitmapIndirect(HBITMAP hBitmap, const BITMAP *pBitmap)
+{
+    if (!rthBmp) STATS_InitializeGDI32 ();
+    RasAddObject (rthBmp, hBitmap, NULL, 0);
+}
+void STATS_DeleteBitmap(HBITMAP hBitmap)
+{
+    RasRemoveObject (rthBmp, hBitmap);
+}
+
+void STATS_DeleteObject(HANDLE hObj, DWORD objtype)
+{
+    switch(objtype) {
+    case OBJ_PEN:
+    case OBJ_EXTPEN:
+        STATS_DeletePen(hObj);
+        break;
+    case OBJ_BRUSH:
+        STATS_DeleteBrush(hObj);
+        break;
+    case OBJ_FONT:
+        STATS_DeleteFont(hObj);
+        break;
+    case OBJ_REGION:
+        STATS_DeleteRgn(hObj);
+        break;
+    case OBJ_BITMAP:
+        STATS_DeleteBitmap(hObj);
+        break;
+
+    case OBJ_MEMDC:
+    case OBJ_DC:
+        STATS_DeleteDC(hObj);
+        break;
+
+    case OBJ_PAL:
+    case OBJ_METAFILE:
+    case OBJ_ENHMETADC:
+    case OBJ_ENHMETAFILE:
+    case OBJ_METADC:
+        break;
+    default:
+        RasLog ("!ERROR! Unknown object %x of type %d", hObj, objtype);
+        break;
+    }
+}
+
+void STATS_DumpStatsGDI32()
+{
+    RasLogObjects(rthDC, RAS_FLAG_LOG_OBJECTS);
+    RasLogObjects(rthPen, RAS_FLAG_LOG_OBJECTS);
+    RasLogObjects(rthBrush, RAS_FLAG_LOG_OBJECTS);
+    RasLogObjects(rthRgn, RAS_FLAG_LOG_OBJECTS);
+    RasLogObjects(rthBmp, RAS_FLAG_LOG_OBJECTS);
+}
+
+void STATS_InitializeGDI32(void)
+{
+    RasEnterSerialize ();
+    if (!rthDC)
+    {
+        RasRegisterObjectTracking(&rthDC, "DC", 0, 0, NULL, NULL);
+    }
+    if (!rthPen)
+    {
+        RasRegisterObjectTracking(&rthPen, "Pen", 0, 0, NULL, NULL);
+    }
+    if (!rthBrush)
+    {
+        RasRegisterObjectTracking(&rthBrush, "Brush", 0, 0, NULL, NULL);
+    }
+    if (!rthRgn)
+    {
+        RasRegisterObjectTracking(&rthRgn, "Region", 0, 0, NULL, NULL);
+    }
+    if (!rthBmp)
+    {
+        RasRegisterObjectTracking(&rthBmp, "Bitmap", 0, 0, NULL, NULL);
+    }
+    RasExitSerialize ();
+}
+
+void STATS_UninitializeGDI32(void)
+{
+// done in RAS kernel    
+//    RasDeregisterObjectTracking(rthDC);
+//    RasDeregisterObjectTracking(rthPen);
+//    RasDeregisterObjectTracking(rthBrush);
+//    RasDeregisterObjectTracking(rthRgn);
+//    RasDeregisterObjectTracking(rthBmp);
+}
+
+#else
 #ifdef DEBUG
 
@@ -316,5 +579,15 @@
 //******************************************************************************
 //******************************************************************************
+void STATS_InitializeGDI32(void)
+{
+    return;
+}
+
+void STATS_UninitializeGDI32(void)
+{
+    return;
+}
 
 
 #endif //DEBUG
+#endif //RAS
Index: trunk/src/gdi32/icm.cpp
===================================================================
--- trunk/src/gdi32/icm.cpp	(revision 21303)
+++ trunk/src/gdi32/icm.cpp	(revision 21304)
@@ -1,3 +1,3 @@
-/* $Id: icm.cpp,v 1.6 2004-04-14 09:44:13 sandervl Exp $ */
+/* $Id: icm.cpp,v 1.5 2004/04/14 09:43:45 sandervl Exp $ */
 
 /*
Index: trunk/src/gdi32/initgdi32.cpp
===================================================================
--- trunk/src/gdi32/initgdi32.cpp	(revision 21303)
+++ trunk/src/gdi32/initgdi32.cpp	(revision 21304)
@@ -95,4 +95,6 @@
    switch (ulFlag) {
       case 0 :
+         STATS_InitializeGDI32 ();         
+
          ParseLogStatusGDI32();
 
@@ -119,4 +121,6 @@
          dprintf(("gdi32 init %s %s (%x)", __DATE__, __TIME__, inittermGdi32));
 
+         RasEntry (RAS_EVENT_Gdi32InitComplete, &dllHandle, sizeof (dllHandle));
+
          break;
       case 1 :
@@ -125,4 +129,5 @@
              UnregisterLxDll(dllHandle);
          }
+         STATS_UninitializeGDI32 ();         
          break;
       default  :
Index: trunk/src/gdi32/objhandle.cpp
===================================================================
--- trunk/src/gdi32/objhandle.cpp	(revision 21303)
+++ trunk/src/gdi32/objhandle.cpp	(revision 21304)
@@ -474,5 +474,5 @@
 
     handleType = GetObjectType(hObj);
-    dprintf2(("GDI32: SelectObject %x %x type %s", hdc, hObj, DbgGetGDITypeName(handleType)));
+    dprintf(("GDI32: SelectObject %x %x type %s", hdc, hObj, DbgGetGDITypeName(handleType)));
     if(handleType == OBJ_REGION) {
         //Return complexity here; not previously selected clip region
Index: trunk/src/gdi32/oslibgpi.cpp
===================================================================
--- trunk/src/gdi32/oslibgpi.cpp	(revision 21303)
+++ trunk/src/gdi32/oslibgpi.cpp	(revision 21304)
@@ -374,11 +374,17 @@
   GpiQueryAttrs(GetDCData(pHps)->hps,PRIM_LINE,LBB_MIX_MODE, (PBUNDLE)&lineBundle);
 
+  ULONG penAttrs = ABB_COLOR | ABB_MIX_MODE | ABB_SYMBOL;
+
   newAreaBundle           = oldAreaBundle;
   newAreaBundle.lColor    = color;
   newAreaBundle.usMixMode = lineBundle.usMixMode;
+  if(!GetDCData(pHps)->isMetaPS && !GetDCData(pHps)->isPrinter) 
+  {
   newAreaBundle.usSet     = LCID_DEFAULT;
+      penAttrs |= ABB_SET;
+  }
   newAreaBundle.usSymbol  = PATSYM_SOLID;
 
-  if (!GpiSetAttrs(GetDCData(pHps)->hps,PRIM_AREA,ABB_COLOR | ABB_MIX_MODE | ABB_SET | ABB_SYMBOL,0,(PBUNDLE)&newAreaBundle))
+  if (!GpiSetAttrs(GetDCData(pHps)->hps,PRIM_AREA, penAttrs,0,(PBUNDLE)&newAreaBundle))
   {
       dprintf(("drawLinePointCircle: GpiSetAttrs failed with %x!!", WinGetLastError(0)));
@@ -386,10 +392,10 @@
   }
 
-  if (GpiFullArc(GetDCData(pHps)->hps,DRO_FILL,MAKEFIXED((width-1)>>1,0)) == GPI_ERROR)
+  if (GpiFullArc(GetDCData(pHps)->hps, GetDCData(pHps)->inPath ? DRO_OUTLINE : DRO_FILL, MAKEFIXED((width-1)>>1,0)) == GPI_ERROR)
   {
       dprintf(("drawLinePointCircle: GpiFullArc failed with %x!!", WinGetLastError(0)));
       rc = FALSE;
   }
-  GpiSetAttrs(GetDCData(pHps)->hps,PRIM_AREA,ABB_COLOR | ABB_MIX_MODE | ABB_SET | ABB_SYMBOL,0,(PBUNDLE)&oldAreaBundle);
+  GpiSetAttrs(GetDCData(pHps)->hps,PRIM_AREA,penAttrs,0,(PBUNDLE)&oldAreaBundle);
 
   return rc;
Index: trunk/src/gdi32/printer.cpp
===================================================================
--- trunk/src/gdi32/printer.cpp	(revision 21303)
+++ trunk/src/gdi32/printer.cpp	(revision 21304)
@@ -1,3 +1,3 @@
-/* $Id: printer.cpp,v 1.3 2004-05-05 09:19:11 sandervl Exp $ */
+/* $Id: printer.cpp,v 1.14 2004/05/04 13:49:24 sandervl Exp $ */
 
 /*
@@ -5,5 +5,5 @@
  *
  * Copyright 2001 Sander van Leeuwen (sandervl@xs4all.nl)
- *
+ * Copyright 2002-2003 InnoTek Systemberatung GmbH (sandervl@innotek.de)
  *
  * Parts based on Wine code (StartDocW)
@@ -19,4 +19,5 @@
 #include <os2win.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <string.h>
 #include <dcdata.h>
@@ -28,4 +29,9 @@
 #include "dbglocal.h"
 
+// Private WGSS escape extensions
+#define PRIVATE_QUERYORIENTATION	0x99990001
+#define PRIVATE_QUERYCOPIES 		0x99990002
+#define PRIVATE_QUERYCOLLATE		0x99990003
+
 static char *lpszPassThrough = NULL;
 static int   cbPassThrough   = 0;
@@ -33,6 +39,22 @@
 //NOTE: We need to insert this postscript statement into the stream or else
 //      the output will be completely inverted (x & y)
-static char  szSetupString[] = "%%BeginSetup\n[{\n%%BeginColorModelSetup\n<< /ProcessColorModel /DeviceCMYK >> setpagedevice\n%%EndColorModelSetup\n} stopped cleartomark\n%%EndSetup\n";
-
+static char  szSetupStringPortrait[]  = "%%BeginSetup\n[{\n%%BeginColorModelSetup\n<< /ProcessColorModel /DeviceCMYK >> setpagedevice\n%%EndColorModelSetup\n} stopped cleartomark\n%%EndSetup\n";
+static char  szSetupStringLandscape[] = "%%BeginSetup\n[{\n%%BeginColorModelSetup\n<< /ProcessColorModel /DeviceCMYK >> setpagedevice\n%%EndColorModelSetup\n} stopped cleartomark\n-90 rotate\n%%EndSetup\n";
+
+
+static BOOL  fPostscriptPassthrough = TRUE;
+
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API ODIN_QueryPostscriptPassthrough()
+{
+    return fPostscriptPassthrough;
+}
+//******************************************************************************
+//******************************************************************************
+void WIN32API ODIN_SetPostscriptPassthrough(BOOL fEnabled)
+{
+    fPostscriptPassthrough = fEnabled;
+}
 //******************************************************************************
 //******************************************************************************
@@ -64,4 +86,39 @@
         dprintf(("Postscript %s data of size %d", lpszEscape, *(WORD *)lpvInData));
 
+        if(fPostscriptPassthrough == FALSE) 
+        {
+            return 0;
+        }
+        if(lpszPassThrough) {
+            O32_Escape(hdc, nEscape, cbPassThrough, lpszPassThrough, NULL);
+            free(lpszPassThrough);
+            lpszPassThrough = NULL;
+        }
+        pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
+        if(pHps && (pHps->Reserved & DC_FLAG_SEND_POSTSCRIPT_SETUP_STRING))
+        { 
+            DWORD dmOrientation = 0, hdrsize, dmCollate, dmCopies;
+            char *pvSetupData = NULL;
+
+            O32_Escape(hdc, PRIVATE_QUERYORIENTATION, 0, NULL, &dmOrientation);
+            if(dmOrientation == DMORIENT_LANDSCAPE) {
+                hdrsize = sizeof(szSetupStringLandscape)-1;
+                pvSetupData = (char *)alloca(hdrsize+sizeof(WORD));
+            }
+            else {//portrait
+                hdrsize = sizeof(szSetupStringPortrait)-1;
+                pvSetupData = (char *)alloca(hdrsize+sizeof(WORD));
+            }
+            if(pvSetupData) {
+                *(WORD *)pvSetupData = hdrsize;
+                memcpy(pvSetupData+sizeof(WORD), (hdrsize == sizeof(szSetupStringPortrait)-1) ? szSetupStringPortrait : szSetupStringLandscape, hdrsize);
+
+                O32_Escape(hdc, nEscape, *(WORD *)pvSetupData, pvSetupData, NULL);
+
+                dprintf(("Send Postscript setup string %d (%x):\n%s", dmOrientation, pHps->Reserved, pvSetupData+sizeof(WORD)));
+            }
+            pHps->Reserved &= ~DC_FLAG_SEND_POSTSCRIPT_SETUP_STRING;
+        }
+
         rc = O32_Escape(hdc, nEscape, cbInput, lpvInData, lpvOutData);
         if(rc == 1) rc = *(WORD *)lpvInData;
@@ -70,4 +127,8 @@
     }
 
+    case PRIVATE_QUERYORIENTATION:
+        DebugInt3();
+        return 0;
+    
     case SPCLPASSTHROUGH2:
     {
@@ -76,4 +137,28 @@
         dprintf(("SPCLPASSTHROUGH2: pretend success"));
         dprintf(("SPCLPASSTHROUGH2: virt mem %x size %x", *(DWORD *)lpvInData, rawsize));
+        if(lpszPassThrough == NULL) {
+            lpszPassThrough = (char *)malloc(rawsize+sizeof(WORD));
+            if(lpszPassThrough == NULL) {
+                DebugInt3();
+                return 0;
+            }
+            memcpy(lpszPassThrough+sizeof(WORD), (char *)lpvInData+6, rawsize);
+            cbPassThrough = rawsize;
+            *(WORD *)lpszPassThrough = (WORD)cbPassThrough;
+        }
+        else {
+            char *tmp = lpszPassThrough;
+
+            lpszPassThrough = (char *)malloc(cbPassThrough+rawsize+sizeof(WORD));
+            if(lpszPassThrough == NULL) {
+                DebugInt3();
+                return 0;
+            }
+            memcpy(lpszPassThrough+sizeof(WORD), tmp+sizeof(WORD), cbPassThrough);
+            free(tmp);
+            memcpy(lpszPassThrough+sizeof(WORD)+cbPassThrough, (char *)lpvInData+6, rawsize);
+            cbPassThrough += rawsize;
+            *(WORD *)lpszPassThrough = (WORD)cbPassThrough;
+        }
         return 1;
     }
@@ -126,4 +211,13 @@
             return Escape(hdc, QUERYESCSUPPORT, sizeof(nEscapeSup), (LPCSTR)&nEscapeSup, NULL);
         }
+        case POSTSCRIPT_PASSTHROUGH:
+        case POSTSCRIPT_DATA:
+        case PASSTHROUGH:
+            if(fPostscriptPassthrough == FALSE) 
+            {
+                return 0;
+            }
+            break;
+
         default:
             break;
