/******************************Module*Header*******************************\ * Module Name: local.h * * * * Definitions needed for client side objects. * * * * Copyright (c) 1993-1999 Microsoft Corporation * \**************************************************************************/ #include "gdispool.h" #include "umpd.h" #include "cliumpd.h" #define MIRRORED_HDC(hdc) (GetLayout(hdc) & LAYOUT_RTL) // // Semaphore utilities // #define INITIALIZECRITICALSECTION(psem) RtlInitializeCriticalSection(psem) #define ENTERCRITICALSECTION(hsem) RtlEnterCriticalSection(hsem) #define LEAVECRITICALSECTION(hsem) RtlLeaveCriticalSection(hsem) #define DELETECRITICALSECTION(psem) RtlDeleteCriticalSection(psem) // // Memory allocation // #define LOCALALLOC(size) RtlAllocateHeap(RtlProcessHeap(),0,size) #define LOCALFREE(pv) (void)RtlFreeHeap(RtlProcessHeap(),0,pv) // // check for multiplication overflow (#define's copied from gre/hmgr.h and // gre/engine.h, respectively; #include required fro PAGE_SIZE definition.) // #include "ntosp.h" #define MAXIMUM_POOL_ALLOC (PAGE_SIZE * 10000) #define BALLOC_OVERFLOW1(c,st) (c > (MAXIMUM_POOL_ALLOC/sizeof(st))) extern DWORD GdiBatchLimit; typedef LPWSTR PWSZ; extern HBRUSH ghbrDCBrush; extern HPEN ghbrDCPen; extern BOOL gbWOW64; #define WOW64PRINTING(pUMPD) ((gbWOW64) && (pUMPD) && ((pUMPD)->pp)) void vUMPDWow64Shutdown(); /**************************************************************************\ * * Local handle macros * \**************************************************************************/ // macros to validate the handles passed in and setup some local variables // for accessing the handle information. #define DC_PLDC(hdc,pldc,Ret) \ pldc = GET_PLDC(hdc); \ if (!pldc || (LO_TYPE(hdc) == LO_METADC16_TYPE)) \ { \ GdiSetLastError(ERROR_INVALID_HANDLE); \ return(Ret); \ } \ ASSERTGDI((pldc->iType == LO_DC) || (pldc->iType == LO_METADC),"DC_PLDC error\n"); #define GET_PLDC(hdc) pldcGet(hdc) #define GET_PMDC(hdc) pmdcGetFromHdc(hdc) #define GET_PMFRECORDER16(pmf,hdc) \ { \ pmf = (PMFRECORDER16)plinkGet(hdc); \ if (pmf) \ pmf = ((PLINK)pmf)->pv; \ } #define hdcFromIhdc(i) GdiFixUpHandle((HANDLE)i) #define pmdcGetFromIhdc(i) pmdcGetFromHdc(GdiFixUpHandle((HANDLE)i)) // ALTDC_TYPE is not LO_ALTDC_TYPE || LO_METADC16_TYPE #define IS_ALTDC_TYPE(h) (LO_TYPE(h) != LO_DC_TYPE) #define IS_METADC16_TYPE(h) (LO_TYPE(h) == LO_METADC16_TYPE) // these macros are defined to aid in determining color vs monochrome pages #define CLEAR_COLOR_PAGE(pldc) pldc->fl &= ~LDC_COLOR_PAGE #define IS_COLOR_GREY(color) ((BYTE)color == (BYTE)(color >> 8) && (BYTE)color == (BYTE)(color >> 16)) #define IS_GREY_MONO(color) ((BYTE)color == (BYTE)0x0 || (BYTE)color == (BYTE)0xff) #define IS_COLOR_MONO(color) ((color & 0x00ffffff) == 0 || (color & 0x00ffffff) == 0x00ffffff) #if 1 // disable debug messages #define DESIGNATE_COLOR_PAGE(pldc) CLEAR_COLOR_PAGE(pldc); #define SET_COLOR_PAGE(pldc) pldc->fl |= LDC_COLOR_PAGE; #define CHECK_COLOR_PAGE(pldc,color) \ { \ if (!IS_COLOR_MONO(color)) \ pldc->fl |= LDC_COLOR_PAGE; \ } #else #define DESIGNATE_COLOR_PAGE(pldc) \ { \ if (pldc->fl & LDC_COLOR_PAGE) \ { \ DbgPrint ("gdi32:Color Page\n"); \ } \ else \ { \ DbgPrint ("gdi32:Monochrome Page\n"); \ } \ CLEAR_COLOR_PAGE(pldc); \ } #define CHECK_COLOR_PAGE(pldc,color) \ { \ if (!IS_COLOR_MONO(color)) \ { \ pldc->fl |= LDC_COLOR_PAGE; \ DbgPrint ("Set Color Page: %08x %s %d\n",color,__FILE__,__LINE__); \ } \ } #define SET_COLOR_PAGE(pldc) \ { \ pldc->fl |= LDC_COLOR_PAGE; \ DbgPrint ("Set color page %s %d\n",__FILE__,__LINE__); \ } #endif /**************************************************************************\ * * LINK stuff * \**************************************************************************/ #define INVALID_INDEX 0xffffffff #define LINK_HASH_SIZE 128 #define H_INDEX(h) ((USHORT)(h)) #define LINK_HASH_INDEX(h) (H_INDEX(h) & (LINK_HASH_SIZE-1)) typedef struct tagLINK { DWORD metalink; struct tagLINK *plinkNext; HANDLE hobj; PVOID pv; } LINK, *PLINK; extern PLINK aplHash[LINK_HASH_SIZE]; PLINK plinkGet(HANDLE h); PLINK plinkCreate(HANDLE h,ULONG ulSize); BOOL bDeleteLink(HANDLE h); HANDLE hCreateClientObjLink(PVOID pv,ULONG ulType); PVOID pvClientObjGet(HANDLE h, DWORD dwLoType); BOOL bDeleteClientObjLink(HANDLE h); int iGetServerType(HANDLE hobj); /**************************************************************************** * * UFI Hash stuff * ***************************************************************************/ typedef struct _MERGEDVIEW { BYTE *pjMem; // pointer to the merged font's memory image ULONG cjMem; // its size } MERGEDVIEW; // info needed for subsetting first and subsequent pages typedef struct _SSINFO { BYTE *pjBits; // glyph index bitfield, one bit set for every glyph // used on pages up to and including this one ULONG cjBits; // cj of the bitfield above ULONG cGlyphsSoFar; // number of bits set in the bitfield above ULONG cDeltaGlyphs; // number of glyphs in the delta for this page BYTE *pjDelta; // bitfield for glyphs in the delta for this page } SSINFO; typedef union _SSMERGE { MERGEDVIEW mvw; // only used on the server SSINFO ssi; // only used on the client } SSMERGE; #define UFI_HASH_SIZE 32 // this should be plenty typedef struct tagUFIHASH { UNIVERSAL_FONT_ID ufi; struct tagUFIHASH *pNext; FSHORT fs1; FSHORT fs2; // client of server side union SSMERGE u; } UFIHASH, *PUFIHASH; #if 0 typedef struct tagUFIHASH { UNIVERSAL_FONT_ID ufi; struct tagUFIHASH *pNext; FSHORT fs1; // server or client, if client delta or not FSHORT fs2; // private or public, dv or not // this part of the structure is only optionally allocated, only needed // for subsetting code. PBYTE pjMemory; ULONG ulMemBytes; // these fields are only used on the client side to do book keeping about // which glyphs from this font are used in the document ULONG ulDistGlyph; ULONG ulDistDelta; PBYTE pjDelta; } UFIHASH, *PUFIHASH; #endif #define FLUFI_SERVER 1 #define FLUFI_DELTA 2 // Define the local DC object. #define PRINT_TIMER 0 #if PRINT_TIMER extern BOOL bPrintTimer; #endif /**************************************************************************** * * PostScript Data * ***************************************************************************/ typedef struct _EMFITEMPSINJECTIONDATA { DWORD cjSize; int nEscape; int cjInput; BYTE EscapeData[1]; } EMFITEMPSINJECTIONDATA, *PEMFITEMPSINJECTIONDATA; typedef struct _PS_INJECTION_DATA { LIST_ENTRY ListEntry; EMFITEMPSINJECTIONDATA EmfData; } PS_INJECTION_DATA, *PPS_INJECTION_DATA; /**************************************************************************** * * Local DC * ***************************************************************************/ typedef struct _LDC { HDC hdc; ULONG fl; ULONG iType; // Metafile information. PVOID pvPMDC; // can't have a PMDC here since it is a class // Printing information. // We need to cache the port name from createDC in case it is not specified at StartDoc LPWSTR pwszPort; ABORTPROC pfnAbort; // Address of application's abort proc. ULONG ulLastCallBack; // Last time we call back to abort proc. HANDLE hSpooler; // handle to the spooler. PUMPD pUMPD; // pointer to user-mode printer driver info KERNEL_PUMDHPDEV pUMdhpdev; // pointer to user-mode pdev info PUFIHASH *ppUFIHash; // used to keep track of fonts used in doc PUFIHASH *ppDVUFIHash; // used to keep track of mm instance fonts used in a doc PUFIHASH *ppSubUFIHash; // used to keep track of subsetted fonts in the doc DEVMODEW *pDevMode; // used to keep trak of ResetDC's UNIVERSAL_FONT_ID ufi; // current UFI used for forced mapping HANDLE hEMFSpool; // information used for recording EMF data #if PRINT_TIMER DWORD msStartDoc; // Time of StartDoc in miliseconds. DWORD msStartPage; // Time of StartPage in miliseconds. #endif DWORD dwSizeOfPSDataToRecord; // Total size of PostScript Injection data to record EMF LIST_ENTRY PSDataList; // List to PostScript Injection data DEVCAPS DevCaps; HBRUSH oldSetDCBrushColorBrush; // Holds latest temp DC brush HPEN oldSetDCPenColorPen; // Holds latest temp DC pen } LDC,*PLDC; // Flags for ldc.fl. #define LDC_SAP_CALLBACK 0x00000020L #define LDC_DOC_STARTED 0x00000040L #define LDC_PAGE_STARTED 0x00000080L #define LDC_CALL_STARTPAGE 0x00000100L #define LDC_NEXTBAND 0x00000200L #define LDC_EMPTYBAND 0x00000400L #define LDC_EMBED_FONTS 0x00001000L #define LDC_META_ARCDIR_CLOCKWISE 0x00002000L #define LDC_FONT_SUBSET 0x00004000L #define LDC_FONT_CHANGE 0x00008000L #define LDC_DOC_CANCELLED 0x00010000L #define LDC_META_PRINT 0x00020000L #define LDC_PRINT_DIRECT 0x00040000L #define LDC_BANDING 0x00080000L #define LDC_DOWNLOAD_FONTS 0x00100000L #define LDC_RESETDC_CALLED 0x00200000L #define LDC_FORCE_MAPPING 0x00400000L #define LDC_LINKED_FONTS 0x00800000L #define LDC_INFO 0x01000000L #define LDC_CACHED_DEVCAPS 0x02000000L #define LDC_ICM_INFO 0x04000000L #define LDC_DOWNLOAD_PROFILES 0x08000000L #define LDC_CALLED_ENDPAGE 0x10000000L #define LDC_COLOR_PAGE 0x20000000L // Values for lMsgSAP. #define MSG_FLUSH 1L // Created thread should flush its message queue. #define MSG_CALL_USER 2L // Created thread should call user. #define MSG_EXIT 3L // Created thread should exit. // TYPE of DC #define LO_DC 0x01 #define LO_METADC 0x02 extern RTL_CRITICAL_SECTION semLocal; // Semaphore for handle management extern RTL_CRITICAL_SECTION semBrush; // semphore for client brush // ahStockObjects will contain both the stock objects visible to an // application, and internal ones such as the private stock bitmap. extern ULONG_PTR ahStockObjects[]; // Declare support functions. HANDLE GdiFixUpHandle(HANDLE h); PLDC pldcGet(HDC hdc); VOID vSetPldc(HDC hdc,PLDC pldc); VOID GdiSetLastError(ULONG iError); HBITMAP GdiConvertBitmap(HBITMAP hbm); HRGN GdiConvertRegion(HRGN hrgn); HDC GdiConvertDC(HDC hdc); HBRUSH GdiConvertBrush(HBRUSH hbrush); VOID vSAPCallback(PLDC); BOOL InternalDeleteDC(HDC hdc,ULONG iType); int GetBrushBits(HDC hdc,HBITMAP hbmRemote,UINT iUsage,DWORD cbBmi, LPVOID pBits,LPBITMAPINFO pBmi); VOID CopyCoreToInfoHeader(LPBITMAPINFOHEADER pbmih,LPBITMAPCOREHEADER pbmch); HBITMAP GetObjectBitmapHandle(HBRUSH hbr, UINT *piUsage); BOOL MonoBitmap(HBITMAP hSrvBitmap); int APIENTRY SetBkModeWOW(HDC hdc,int iMode); int APIENTRY SetPolyFillModeWOW(HDC hdc,int iMode); int APIENTRY SetROP2WOW(HDC hdc,int iMode); int APIENTRY SetStretchBltModeWOW(HDC hdc,int iMode); UINT APIENTRY SetTextAlignWOW(HDC hdc,UINT iMode); HMETAFILE WINAPI SetMetaFileBitsAlt(HLOCAL); HENHMETAFILE APIENTRY SetEnhMetaFileBitsAlt(HLOCAL, HANDLE, HANDLE, UINT64); BOOL InternalDeleteEnhMetaFile(HENHMETAFILE hemf, BOOL bAllocBuffer); BOOL SetFontXform(HDC hdc,FLOAT exScale,FLOAT eyScale); BOOL DeleteObjectInternal(HANDLE h); DWORD GetServerObjectType(HGDIOBJ h); BOOL MakeInfoDC(HDC hdc,BOOL bSet); BOOL GetDCPoint(HDC hdc,DWORD i,PPOINT pptOut); HANDLE CreateClientObj(ULONG ulType); BOOL DeleteClientObj(HANDLE h); PLDC pldcCreate(HDC hdc,ULONG ulType); BOOL bDeleteLDC(PLDC pldc); BOOL bGetANSISetMap(); HANDLE CreateTempSpoolFile(); // Some convenient defines. typedef BITMAPINFO BMI; typedef PBITMAPINFO PBMI; typedef LPBITMAPINFO LPBMI; typedef BITMAPINFOHEADER BMIH; typedef PBITMAPINFOHEADER PBMIH; typedef LPBITMAPINFOHEADER LPBMIH; typedef BITMAPCOREINFO BMC; typedef PBITMAPCOREINFO PBMC; typedef LPBITMAPCOREINFO LPBMC; typedef BITMAPCOREHEADER BMCH; typedef PBITMAPCOREHEADER PBMCH; typedef LPBITMAPCOREHEADER LPBMCH; #define NEG_INFINITY 0x80000000 #define POS_INFINITY 0x7fffffff // Check if a source is needed in a 3-way bitblt operation. // This works on both rop and rop3. We assume that a rop contains zero // in the high byte. // // This is tested by comparing the rop result bits with source (column A // below) vs. those without source (column B). If the two cases are // identical, then the effect of the rop does not depend on the source // and we don't need a source device. Recall the rop construction from // input (pattern, source, target --> result): // // P S T | R A B mask for A = 0CCh // ------+-------- mask for B = 33h // 0 0 0 | x 0 x // 0 0 1 | x 0 x // 0 1 0 | x x 0 // 0 1 1 | x x 0 // 1 0 0 | x 0 x // 1 0 1 | x 0 x // 1 1 0 | x x 0 // 1 1 1 | x x 0 #define ISSOURCEINROP3(rop3) \ (((rop3) & 0xCCCC0000) != (((rop3) << 2) & 0xCCCC0000)) #define MIN(A,B) ((A) < (B) ? (A) : (B)) #define MAX(A,B) ((A) > (B) ? (A) : (B)) #define MAX4(a, b, c, d) max(max(max(a,b),c),d) #define MIN4(a, b, c, d) min(min(min(a,b),c),d) // // Win31 compatibility stuff. // see user\client // DWORD GetAppCompatFlags(KERNEL_PVOID); DWORD GetAppCompatFlags2(WORD); // defined in w32\w32inc\usergdi.h #define ABS(X) (((X) < 0 ) ? -(X) : (X)) #define META int GetBreakExtra (HDC hdc); int GetcBreak (HDC hdc); HANDLE GetDCObject (HDC, int); DWORD GetDCDWord(HDC hdc,UINT index,INT error ); #if DBG extern int gerritv; #define MFD1(X) { if(gerritv) DbgPrint(X); } #define MFD2(X,Y) { if(gerritv) DbgPrint(X,Y); } #define MFD3(X,Y,Z) { if(gerritv) DbgPrint(X,Y,Z); } #else #define MFD1(X) #define MFD2(X,Y) #define MFD3(X,Y,Z) #endif BOOL AssociateEnhMetaFile(HDC); HENHMETAFILE UnassociateEnhMetaFile(HDC, BOOL); ULONG ulToASCII_N(LPSTR psz, DWORD cbAnsi, LPWSTR pwsz, DWORD c); DWORD GetAndSetDCDWord( HDC, UINT, UINT, UINT, WORD, UINT ); #ifdef DBCS #define gbDBCSCodeOn TRUE #endif /**************************************************************************\ * * SPOOLER Linking routines. We don't want to staticly link to the spooler * so that it doesn't need to be brought in until necesary. * * 09-Aug-1994 -by- Eric Kutter [erick] * \**************************************************************************/ BOOL bLoadSpooler(); #define BLOADSPOOLER ((ghSpooler != NULL) || bLoadSpooler()) typedef LPWSTR (FAR WINAPI * FPSTARTDOCDLGW)(HANDLE,CONST DOCINFOW *); typedef BOOL (FAR WINAPI * FPOPENPRINTERW)(LPWSTR,LPHANDLE,LPPRINTER_DEFAULTSW); typedef BOOL (FAR WINAPI * FPRESETPRINTERW)(HANDLE,LPPRINTER_DEFAULTSW); typedef BOOL (FAR WINAPI * FPCLOSEPRINTER)(HANDLE); typedef BOOL (FAR WINAPI * FPGETPRINTERW)(HANDLE,DWORD,LPBYTE,DWORD,LPDWORD); typedef BOOL (FAR WINAPI * FPGETPRINTERDRIVERW)(HANDLE,LPWSTR,DWORD,LPBYTE,DWORD,LPDWORD); typedef BOOL (FAR WINAPI * FPENDDOCPRINTER)(HANDLE); typedef BOOL (FAR WINAPI * FPENDPAGEPRINTER)(HANDLE); typedef BOOL (FAR WINAPI * FPREADPRINTER)(HANDLE,LPVOID,DWORD,LPDWORD); typedef BOOL (FAR WINAPI * FPSPLREADPRINTER)(HANDLE,LPBYTE *,DWORD); typedef DWORD (FAR WINAPI * FPSTARTDOCPRINTERW)(HANDLE,DWORD,LPBYTE); typedef BOOL (FAR WINAPI * FPSTARTPAGEPRINTER)(HANDLE); typedef BOOL (FAR WINAPI * FPWRITERPRINTER)(HANDLE,LPVOID,DWORD,LPDWORD); typedef BOOL (FAR WINAPI * FPABORTPRINTER)(HANDLE); typedef BOOL (FAR WINAPI * FPQUERYSPOOLMODE)(HANDLE,FLONG*,ULONG*); typedef INT (FAR WINAPI * FPQUERYREMOTEFONTS)(HANDLE,PUNIVERSAL_FONT_ID,ULONG); typedef BOOL (FAR WINAPI * FPSEEKPRINTER)(HANDLE,LARGE_INTEGER,PLARGE_INTEGER,DWORD,BOOL); typedef BOOL (FAR WINAPI * FPQUERYCOLORPROFILE)(HANDLE,PDEVMODEW,ULONG,PVOID,ULONG*,FLONG*); typedef VOID (FAR WINAPI * FPSPLDRIVERUNLOADCOMPLETE)(LPWSTR); typedef HANDLE (FAR WINAPI * FPGETSPOOLFILEHANDLE)(HANDLE); typedef HANDLE (FAR WINAPI * FPCOMMITSPOOLDATA)(HANDLE, HANDLE, DWORD); typedef BOOL (FAR WINAPI * FPCLOSESPOOLFILEHANDLE)(HANDLE, HANDLE); typedef LONG (FAR WINAPI * FPDOCUMENTPROPERTIESW)(HWND,HANDLE,LPWSTR,PDEVMODEW,PDEVMODEW,DWORD); typedef DWORD (FAR WINAPI * FPLOADSPLWOW64)(HANDLE *hProcess); typedef BOOL (FAR WINAPI * FPISVALIDDEVMODEW)(PDEVMODEW pDevmode, SIZE_T size); extern HINSTANCE ghSpooler; extern FPSTARTDOCDLGW fpStartDocDlgW; extern FPOPENPRINTERW fpOpenPrinterW; extern FPRESETPRINTERW fpResetPrinterW; extern FPCLOSEPRINTER fpClosePrinter; extern FPGETPRINTERW fpGetPrinterW; extern FPGETPRINTERDRIVERW fpGetPrinterDriverW; extern PFNDOCUMENTEVENT fpDocumentEvent; extern FPQUERYCOLORPROFILE fpQueryColorProfile; extern FPSPLDRIVERUNLOADCOMPLETE fpSplDriverUnloadComplete; extern FPENDDOCPRINTER fpEndDocPrinter; extern FPENDPAGEPRINTER fpEndPagePrinter; extern FPSPLREADPRINTER fpSplReadPrinter; extern FPREADPRINTER fpReadPrinter; extern FPSTARTDOCPRINTERW fpStartDocPrinterW; extern FPSTARTPAGEPRINTER fpStartPagePrinter; extern FPABORTPRINTER fpAbortPrinter; extern FPQUERYSPOOLMODE fpQuerySpoolMode; extern FPQUERYREMOTEFONTS fpQueryRemoteFonts; extern FPSEEKPRINTER fpSeekPrinter; extern FPGETSPOOLFILEHANDLE fpGetSpoolFileHandle; extern FPCOMMITSPOOLDATA fpCommitSpoolData; extern FPCLOSESPOOLFILEHANDLE fpCloseSpoolFileHandle; extern FPDOCUMENTPROPERTIESW fpDocumentPropertiesW; extern FPLOADSPLWOW64 fpLoadSplWow64; extern FPISVALIDDEVMODEW fpIsValidDevmodeW; int DocumentEventEx(PUMPD, HANDLE, HDC, INT, ULONG, PVOID, ULONG, PVOID); DWORD StartDocPrinterWEx(PUMPD, HANDLE, DWORD, LPBYTE); BOOL EndDocPrinterEx(PUMPD, HANDLE); BOOL StartPagePrinterEx(PUMPD, HANDLE); BOOL EndPagePrinterEx(PUMPD, HANDLE); BOOL AbortPrinterEx(PLDC, BOOL); BOOL ResetPrinterWEx(PLDC, PRINTER_DEFAULTSW *); BOOL QueryColorProfileEx(PLDC, PDEVMODEW, ULONG, PVOID, ULONG *, FLONG *); extern BOOL MFP_StartDocA(HDC hdc, CONST DOCINFOA * pDocInfo, BOOL bBanding ); extern BOOL MFP_StartDocW(HDC hdc, CONST DOCINFOW * pDocInfo, BOOL bBanding ); extern int MFP_StartPage(HDC hdc ); extern int MFP_EndPage(HDC hdc ); extern int MFP_EndFormPage(HDC hdc ); extern int MFP_EndDoc(HDC hdc); extern BOOL MFP_ResetBanding( HDC hdc, BOOL bBanding ); extern BOOL MFP_ResetDCW( HDC hdc, DEVMODEW *pdmw ); extern int DetachPrintMetafile( HDC hdc ); extern HDC ResetDCWInternal(HDC hdc, CONST DEVMODEW *pdm, BOOL *pbBanding); extern BOOL PutDCStateInMetafile( HDC hdcMeta ); //font subsetting routines typedef void *(WINAPIV *CFP_ALLOCPROC) (size_t); typedef void *(WINAPIV *CFP_REALLOCPROC) (void *, size_t); typedef void (WINAPIV *CFP_FREEPROC) (void *); typedef SHORT (FAR WINAPIV * FPCREATEFONTPACKAGE)(const PUCHAR, const ULONG, PUCHAR*, ULONG*, ULONG*, const USHORT, const USHORT, const USHORT, const USHORT, const USHORT, const USHORT, const PUSHORT, const USHORT, CFP_ALLOCPROC, CFP_REALLOCPROC, CFP_FREEPROC, void*); typedef SHORT (FAR WINAPIV * FPMERGEFONTPACKAGE)(const PUCHAR, const ULONG, const PUCHAR, const ULONG, PUCHAR*, ULONG*, ULONG*, const USHORT, CFP_ALLOCPROC, CFP_REALLOCPROC, CFP_FREEPROC, void*); extern FPCREATEFONTPACKAGE gfpCreateFontPackage; extern FPMERGEFONTPACKAGE gfpMergeFontPackage; // gulMaxCig is used to decide whether font subset should be used for remote printing extern ULONG gulMaxCig; #if DBG #define DBGSUBSET 1 #endif #ifdef DBGSUBSET extern FLONG gflSubset; #define FL_SS_KEEPLIST 1 #define FL_SS_BUFFSIZE 2 #define FL_SS_SPOOLTIME 4 #define FL_SS_PAGETIME 8 #define FL_SS_SUBSETTIME 16 #endif // DBGSUBSET /**************************************************************************\ * * EMF structures. * * EMFSPOOLHEADER - first thing in a spool file * * EMFITEMHEADER - defines items (blocks) of a metafile. This includes * fonts, pages, new devmode, list of things to do before * first start page. * * cjSize is the size of the data following the header * * \**************************************************************************/ // // Round up n to the nearest multiple of sizeof(DWORD) // (also provide a boolean macro to which returns true of the roundup // calculation would overflow) #define ROUNDUP_DWORDALIGN(n) (((n) + sizeof(DWORD) - 1) & ~(sizeof(DWORD)-1)) #define BROUNDUP_DWORDALIGN_OVERFLOW(n) (((unsigned)((n)+(sizeof(DWORD)-1)) < (n)) ? 1 : 0) typedef struct tagEMFSPOOLHEADER { DWORD dwVersion; // version of this EMF spoolfile DWORD cjSize; // size of this structure DWORD dpszDocName; // offset to lpszDocname value of DOCINFO struct DWORD dpszOutput; // offset to lpszOutput value of DOCINFO struct } EMFSPOOLHEADER; #define EMRI_METAFILE 0x00000001 #define EMRI_ENGINE_FONT 0x00000002 #define EMRI_DEVMODE 0x00000003 #define EMRI_TYPE1_FONT 0x00000004 #define EMRI_PRESTARTPAGE 0x00000005 #define EMRI_DESIGNVECTOR 0x00000006 #define EMRI_SUBSET_FONT 0x00000007 #define EMRI_DELTA_FONT 0x00000008 #define EMRI_FORM_METAFILE 0x00000009 #define EMRI_BW_METAFILE 0x0000000A #define EMRI_BW_FORM_METAFILE 0x0000000B #define EMRI_METAFILE_DATA 0x0000000C #define EMRI_METAFILE_EXT 0x0000000D #define EMRI_BW_METAFILE_EXT 0x0000000E #define EMRI_ENGINE_FONT_EXT 0x0000000F #define EMRI_TYPE1_FONT_EXT 0x00000010 #define EMRI_DESIGNVECTOR_EXT 0x00000011 #define EMRI_SUBSET_FONT_EXT 0x00000012 #define EMRI_DELTA_FONT_EXT 0x00000013 #define EMRI_PS_JOB_DATA 0x00000014 #define EMRI_EMBED_FONT_EXT 0x00000015 #define EMF_PLAY_COLOR 0x00000001 // Current DC has DMCOLOR_COLOR #define EMF_PLAY_MONOCHROME 0x00000002 // Changed by Optimization code to MONOCHROME #define EMF_PLAY_FORCE_MONOCHROME 0x00000003 // Changed to MONOCHROME in the spool file #define NORMAL_PAGE 1 #define FORM_PAGE 2 typedef struct tagEMFITEMHEADER { DWORD ulID; // either EMRI_METAFILE or EMRI_FONT DWORD cjSize; // size of item in bytes } EMFITEMHEADER; // // EMF spool file record structure for the following record types: // EMRI_METAFILE_EXT // EMRI_BW_METAFILE_EXT // EMRI_ENGINE_FONT_EXT // EMRI_TYPE1_FONT_EXT // EMRI_DESIGNVECTOR_EXT // EMRI_SUBSET_FONT_EXT // EMRI_DELTA_FONT_EXT // typedef struct tagEMFITEMHEADER_EXT { EMFITEMHEADER emfi; INT64 offset; } EMFITEMHEADER_EXT; typedef struct tagEMFITEMPRESTARTPAGE { ULONG ulUnused; // originally ulCopyCount BOOL bEPS; }EMFITEMPRESTARTPAGE, *PEMFITEMPRESTARTPAGE; typedef struct tagRECORD_INFO_STRUCT { struct tagRECORD_INFO_STRUCT *pNext; LONGLONG RecordOffset; ULONG RecordSize; DWORD RecordID; } RECORD_INFO_STRUCT, *PRECORD_INFO_STRUCT; typedef struct tagPAGE_INFO_STRUCT { LONGLONG EMFOffset; LONGLONG SeekOffset; LPDEVMODEW pDevmode; ULONG EMFSize; ULONG ulID; PRECORD_INFO_STRUCT pRecordInfo; } PAGE_INFO_STRUCT; typedef struct tagPAGE_LAYOUT_STRUCT { HENHMETAFILE hemf; DWORD dwPageNumber; XFORM XFormDC; RECT rectClip; RECT rectDocument; RECT rectBorder; BOOL bAllocBuffer; } PAGE_LAYOUT_STRUCT; typedef struct tagEMF_HANDLE { DWORD tag; DWORD dwPageNumber; HENHMETAFILE hemf; BOOL bAllocBuffer; struct tagEMF_HANDLE *pNext; } EMF_HANDLE, *PEMF_HANDLE; typedef struct tagEMF_LIST { HENHMETAFILE hemf; BOOL bAllocBuffer; struct tagEMF_LIST *pNext; } EMF_LIST, *PEMF_LIST; typedef struct tagSPOOL_FILE_HANDLE { DWORD tag; HDC hdc; HANDLE hSpooler; LPDEVMODEW pOriginalDevmode; LPDEVMODEW pLastDevmode; ULONG MaxPageProcessed; PAGE_INFO_STRUCT *pPageInfo; ULONG PageInfoBufferSize; DWORD dwNumberOfPagesInCurrSide; BOOL bBanding; PAGE_LAYOUT_STRUCT *pPageLayout; DWORD dwNumberOfPagesAllocated; PEMF_HANDLE pEMFHandle; DWORD dwPlayBackStatus; BOOL bUseMemMap; } SPOOL_FILE_HANDLE; #define SPOOL_FILE_HANDLE_TAG 'SPHT' #define SPOOL_FILE_MAX_NUMBER_OF_PAGES_PER_SIDE 32 #define EMF_HANDLE_TAG 'EFHT' /**************************************************************************\ * * stuff from csgdi.h * \**************************************************************************/ // // Win32ClientInfo[WIN32_CLIENT_INFO_SPIN_COUNT] corresponds to the // cSpins field of the CLIENTINFO structure. See ntuser\inc\user.h. // #define RESETUSERPOLLCOUNT() ((DWORD)NtCurrentTebShared()->Win32ClientInfo[WIN32_CLIENT_INFO_SPIN_COUNT] = 0) ULONG cjBitmapSize(CONST BITMAPINFO *pbmi,ULONG iUsage); ULONG cjBitmapBitsSize(CONST BITMAPINFO *pbmi); ULONG cjBitmapScanSize(CONST BITMAPINFO *pbmi, int nScans); BITMAPINFOHEADER * pbmihConvertHeader (BITMAPINFOHEADER *pbmih); LPBITMAPINFO pbmiConvertInfo(CONST BITMAPINFO *, ULONG, ULONG * ,BOOL); // // object.c // HANDLE hGetPEBHandle(HANDLECACHETYPE,ULONG); BOOL bDIBSectionSelected(PDC_ATTR); PDEVMODEW pdmwGetDefaultDevMode( HANDLE hSpooler, PUNICODE_STRING pustrDevice, // device name PVOID *ppvFree // *ppvFree must be freed by the caller ); /**************************************************************************\ * DIB flags. These flags are merged with the usage field when calling * cjBitmapSize to specify what the size should include. Any routine that * uses these flags should first use the macro, CHECKDIBFLAGS(iUsage) to * return an error if one of these bits is set. If the definition of * iUsage changes and one of these flags becomes a valid flag, the interface * will need to be changed slightly. * * 04-June-1991 -by- Eric Kutter [erick] \**************************************************************************/ #define DIB_MAXCOLORS 0x80000000 #define DIB_NOCOLORS 0x40000000 #define DIB_LOCALFLAGS (DIB_MAXCOLORS | DIB_NOCOLORS) #define CHECKDIBFLAGS(i) {if (i & DIB_LOCALFLAGS) \ {RIP("INVALID iUsage"); goto MSGERROR;}} #define HANDLE_TO_INDEX(h) (DWORD)((ULONG_PTR)h & 0x0000ffff) /******************************Public*Macro********************************\ * * PSHARED_GET_VALIDATE * * Validate all handle information, return user pointer if the handle * is valid or NULL otherwise. * * Arguments: * * p - pointer to assign to pUser is successful * h - handle to object * iType - handle type * \**************************************************************************/ #pragma warning(4:4821) // Disable all ptr64->ptr32 truncation warnings for now #define PSHARED_GET_VALIDATE(p,h,iType) \ { \ UINT uiIndex = HANDLE_TO_INDEX(h); \ p = NULL; \ \ if (uiIndex < MAX_HANDLE_COUNT) \ { \ PENTRY pentry = &pGdiSharedHandleTable[uiIndex]; \ \ if ( \ (pentry->Objt == iType) && \ (pentry->FullUnique == (USHORT)((ULONG_PTR)h >> 16)) && \ (OBJECTOWNER_PID(pentry->ObjectOwner) == gW32PID) \ ) \ { \ p = (PVOID)(ULONG_PTR)pentry->pUser; \ } \ } \ } #define VALIDATE_HANDLE(bRet, h,iType) \ { \ UINT uiIndex = HANDLE_TO_INDEX(h); \ bRet = FALSE; \ \ if (uiIndex < MAX_HANDLE_COUNT) \ { \ PENTRY pentry = &pGdiSharedHandleTable[uiIndex]; \ \ if ( \ (pentry->Objt == iType) && \ ((pentry->FullUnique&~FULLUNIQUE_STOCK_MASK) == \ (((USHORT)((ULONG_PTR)h >> 16))&~FULLUNIQUE_STOCK_MASK)) &&\ ((OBJECTOWNER_PID(pentry->ObjectOwner) == gW32PID) || \ (OBJECTOWNER_PID(pentry->ObjectOwner) == 0)) \ ) \ { \ bRet = TRUE; \ } \ } \ } #define VALIDATE_HANDLE_AND_STOCK(bRet, h, iType, bStock) \ { \ UINT uiIndex = HANDLE_TO_INDEX(h); \ bRet = FALSE; \ bStock = FALSE; \ \ if (uiIndex < MAX_HANDLE_COUNT) \ { \ PENTRY pentry = &pGdiSharedHandleTable[uiIndex]; \ \ if ( \ (pentry->Objt == iType) && \ ((pentry->FullUnique&~FULLUNIQUE_STOCK_MASK) == \ (((USHORT)((ULONG_PTR)h >> 16))&~FULLUNIQUE_STOCK_MASK)) &&\ ((OBJECTOWNER_PID(pentry->ObjectOwner) == gW32PID) || \ (OBJECTOWNER_PID(pentry->ObjectOwner) == 0)) \ ) \ { \ bRet = TRUE; \ bStock = (pentry->FullUnique & FULLUNIQUE_STOCK_MASK); \ } \ } \ } // // // DC_ATTR support // // // extern PGDI_SHARED_MEMORY pGdiSharedMemory; extern PDEVCAPS pGdiDevCaps; extern PENTRY pGdiSharedHandleTable; extern W32PID gW32PID; #define SHARECOUNT(hbrush) (pGdiSharedHandleTable[HANDLE_TO_INDEX(h)].ObjectOwner.Share.Count) /******************************Public*Routine******************************\ * * FSHARED_DCVALID_RAO - check Valid RAO flag in the handle table entry for * the hdc * * Arguments: * * hdc * * Return Value: * * BOOL flag value * \**************************************************************************/ #define FSHARED_DCVALID_RAO(hdc) \ (pGdiSharedHandleTable[HDC_TO_INDEX(hdc)].Flags & \ HMGR_ENTRY_VALID_RAO) BOOL DeleteRegion(HRGN); /******************************Public*Macro********************************\ * ORDER_PRECT makes the rect well ordered * * Arguments: * * PRECTL prcl * \**************************************************************************/ #define ORDER_PRECTL(prcl) \ { \ LONG lt; \ \ if (prcl->left > prcl->right) \ { \ lt = prcl->left; \ prcl->left = prcl->right; \ prcl->right = lt; \ } \ \ if (prcl->top > prcl->bottom) \ { \ lt = prcl->top; \ prcl->top = prcl->bottom; \ prcl->bottom = lt; \ } \ } // // client region defines and structures // #define CONTAINED 1 #define CONTAINS 2 #define DISJOINT 3 #define VALID_SCR(X) (!((X) & 0xF8000000) || (((X) & 0xF8000000) == 0xF8000000)) #define VALID_SCRPT(P) ((VALID_SCR((P).x)) && (VALID_SCR((P).y))) #define VALID_SCRPPT(P) ((VALID_SCR((P)->x)) && (VALID_SCR((P)->y))) #define VALID_SCRRC(R) ((VALID_SCR((R).left)) && (VALID_SCR((R).bottom)) && \ (VALID_SCR((R).right)) && (VALID_SCR((R).top))) #define VALID_SCRPRC(R) ((VALID_SCR((R)->left)) && (VALID_SCR((R)->bottom)) && \ (VALID_SCR((R)->right)) && (VALID_SCR((R)->top))) int iRectRelation(PRECTL prcl1, PRECTL prcl2); int APIENTRY GetRandomRgn(HDC hdc,HRGN hrgn,int iNum); #define vReferenceCFONTCrit(pcf) {(pcf)->cRef++;} DWORD GetCodePage(HDC hdc); #define FLOATARG(f) (*(PULONG)(PFLOAT)&(f)) #define FLOATPTRARG(pf) ((PULONG)(pf)) /******************************Public*Macros******************************\ * FIXUP_HANDLE(h) and FIXUP_HANDLEZ(h) * * check to see if the handle has been truncated. * FIXUP_HANDLEZ() adds an extra check to allow NULL. * * Arguments: * h - handle to be checked and fix * * Return Value: * * History: * * 25-Jan-1996 -by- Lingyun Wang [lingyunw] * \**************************************************************************/ #define HANDLE_FIXUP 0 #if DBG extern INT gbCheckHandleLevel; #endif #define NEEDS_FIXING(h) (!((ULONG_PTR)h & 0xffff0000)) #if DBG #define HANDLE_WARNING() \ { \ if (gbCheckHandleLevel == 1) \ { \ WARNING ("truncated handle\n"); \ } \ ASSERTGDI (gbCheckHandleLevel != 2, "truncated handle\n"); \ } #else #define HANDLE_WARNING() #endif #if DBG #define CHECK_HANDLE_WARNING(h, bZ) \ { \ BOOL bFIX = NEEDS_FIXING(h); \ \ if (bZ) bFIX = h && bFIX; \ \ if (bFIX) \ { \ if (gbCheckHandleLevel == 1) \ { \ WARNING ("truncated handle\n"); \ } \ ASSERTGDI (gbCheckHandleLevel != 2, "truncated handle\n"); \ } \ } #else #define CHECK_HANDLE_WARNING(h,bZ) #endif #if HANDLE_FIXUP #define FIXUP_HANDLE(h) \ { \ if (NEEDS_FIXING(h)) \ { \ HANDLE_WARNING(); \ h = GdiFixUpHandle(h); \ } \ } #else #define FIXUP_HANDLE(h) \ { \ CHECK_HANDLE_WARNING(h,FALSE); \ } #endif #if HANDLE_FIXUP #define FIXUP_HANDLEZ(h) \ { \ if (h && NEEDS_FIXING(h)) \ { \ HANDLE_WARNING(); \ h = GdiFixUpHandle(h); \ } \ } #else #define FIXUP_HANDLEZ(h) \ { \ CHECK_HANDLE_WARNING(h,TRUE); \ } #endif #define FIXUP_HANDLE_NOW(h) \ { \ if (NEEDS_FIXING(h)) \ { \ HANDLE_WARNING(); \ h = GdiFixUpHandle(h); \ } \ } /******************************MACRO***************************************\ * CHECK_AND_FLUSH * * Check if commands in the batch need to be flushed based on matching * hdc * * Arguments: * * hdc * * History: * * 14-Feb-1996 -by- Mark Enstrom [marke] * \**************************************************************************/ #define CHECK_AND_FLUSH(hdc, pdca) \ { \ if ((NtCurrentTebShared()->GdiTebBatch.HDC == (ULONG_PTR)hdc) \ && (pdca->ulDirty_ & BATCHED_DRAWING) \ ) \ { \ NtGdiFlush(); \ pdca->ulDirty_ &= ~BATCHED_DRAWING; \ } \ } #define CHECK_AND_FLUSH_TEXT(hdc, pdca) \ { \ if ((NtCurrentTebShared()->GdiTebBatch.HDC == (ULONG_PTR)hdc) \ && (pdca->ulDirty_ & BATCHED_TEXT) \ ) \ { \ NtGdiFlush(); \ pdca->ulDirty_ &= ~BATCHED_TEXT; \ pdca->ulDirty_ &= ~BATCHED_DRAWING; \ } \ } #if defined(_WIN64) || defined(BUILD_WOW6432) #define KHANDLE_ALIGN(size) ((size + sizeof(KHANDLE) - 1) & ~(sizeof(KHANDLE) - 1)) #else // no alignment issues on regular 32-bit #define KHANDLE_ALIGN(size) (size) #endif /*********************************MACRO************************************\ * BEGIN_BATCH_HDC * * Attemp to place the command in the TEB batch. This macro is for use * with commands requiring an HDC * * Arguments: * * hdc - hdc of command * pdca - PDC_ATTR from hdc * cType - enum bathc command type * StrType - specific BATCH structure * * Return Value: * * none: will jump to UNBATHCED_COMMAND if command can't be batched * * History: * * 22-Feb-1996 -by- Mark Enstrom [marke] * \**************************************************************************/ #define BEGIN_BATCH_HDC(hdc,pdca,cType,StrType) \ { \ PTEBSHARED ptebShared = NtCurrentTebShared(); \ StrType *pBatch; \ HDC hdcBatch = hdc; \ \ if (!( \ ( \ (ptebShared->GdiTebBatch.HDC == 0) || \ (ptebShared->GdiTebBatch.HDC == (ULONG_PTR)hdc) \ ) && \ ((ptebShared->GdiTebBatch.Offset + KHANDLE_ALIGN(sizeof(StrType))) <= GDI_BATCH_SIZE) && \ (pdca != NULL) && \ (!(pdca->ulDirty_ & DC_DIBSECTION)) \ )) \ { \ goto UNBATCHED_COMMAND; \ } \ \ pBatch = (StrType *)( \ ((PBYTE)(&ptebShared->GdiTebBatch.Buffer[0])) + \ ptebShared->GdiTebBatch.Offset \ ); \ \ pBatch->Type = cType; \ pBatch->Length = KHANDLE_ALIGN(sizeof(StrType)); \ \ if (cType < BatchTypeSetBrushOrg) \ { \ pdca->ulDirty_ |= BATCHED_DRAWING; \ } \ \ if (cType == BatchTypeTextOut) \ { \ pdca->ulDirty_ |= BATCHED_TEXT; \ } /*********************************MACRO************************************\ * BEGIN_BATCH_HDC * * Attemp to place the command in the TEB batch. This macro is for use * with commands requiring an HDC * * Arguments: * * hdc - hdc of command * pdca - PDC_ATTR from hdc * cType - enum bathc command type * StrType - specific BATCH structure * * Return Value: * * none: will jump to UNBATHCED_COMMAND if command can't be batched * * History: * * 22-Feb-1996 -by- Mark Enstrom [marke] * \**************************************************************************/ #define BEGIN_BATCH_HDC_SIZE(hdc,pdca,cType,StrType,Size) \ { \ PTEBSHARED ptebShared = NtCurrentTebShared(); \ StrType *pBatch; \ HDC hdcBatch = hdc; \ \ if (!( \ ( \ (ptebShared->GdiTebBatch.HDC == 0) || \ (ptebShared->GdiTebBatch.HDC == (ULONG_PTR)hdc) \ ) && \ ((ptebShared->GdiTebBatch.Offset + KHANDLE_ALIGN(Size)) <= GDI_BATCH_SIZE) && \ (pdca != NULL) && \ (!(pdca->ulDirty_ & DC_DIBSECTION)) \ )) \ { \ goto UNBATCHED_COMMAND; \ } \ \ pBatch = (StrType *)( \ ((PBYTE)(&ptebShared->GdiTebBatch.Buffer[0])) + \ ptebShared->GdiTebBatch.Offset \ ); \ \ pBatch->Type = cType; \ pBatch->Length = KHANDLE_ALIGN(Size); \ \ if (cType < BatchTypeSetBrushOrg) \ { \ pdca->ulDirty_ |= BATCHED_DRAWING; \ } \ \ if (cType == BatchTypeTextOut) \ { \ pdca->ulDirty_ |= BATCHED_TEXT; \ } /*********************************MACRO************************************\ * BEGIN_BATCH * * Attemp to place the command in the TEB batch. This macro is for use * with commands that don't require an HDC * * Arguments: * * cType - enum bathc command type * StrType - specific BATCH structure * * Return Value: * * none: will jump to UNBATHCED_COMMAND if command can't be batched * * Notes: * * The "Win32ThreadInfo==NULL" check fixes "issue 2" of bug #338052. * * If the thread is not a GUI thread, we can't batch non-HDC operations, * because we can't guarantee that the batch will be flushed before the * thread exits. (GdiThreadCallout isn't called unless the thread is a GUI * thread.) * * History: * * 22-Feb-1996 -by- Mark Enstrom [marke] * \**************************************************************************/ #define BEGIN_BATCH(cType,StrType) \ { \ PTEBSHARED ptebShared = NtCurrentTebShared(); \ StrType *pBatch; \ HDC hdcBatch = NULL; \ \ if (ptebShared->Win32ThreadInfo == NULL) \ { \ goto UNBATCHED_COMMAND; \ } \ \ if (! \ ((ptebShared->GdiTebBatch.Offset + KHANDLE_ALIGN(sizeof(StrType))) <= GDI_BATCH_SIZE) \ ) \ { \ goto UNBATCHED_COMMAND; \ } \ \ pBatch = (StrType *)( \ ((PBYTE)(&ptebShared->GdiTebBatch.Buffer[0])) + \ ptebShared->GdiTebBatch.Offset \ ); \ \ pBatch->Type = cType; \ pBatch->Length = KHANDLE_ALIGN(sizeof(StrType)); \ /*********************************MACRO************************************\ * COMPLETE_BATCH_COMMAND * * Complete batched command started with BEGIN_BATCH or BEGIN_BATCH_HDC. * The command is not actually batched unless this macro is executed. * * Arguments: * * None * * Return Value: * * None * * History: * * 22-Feb-1996 -by- Mark Enstrom [marke] * \**************************************************************************/ #define COMPLETE_BATCH_COMMAND() \ if (hdcBatch) \ { \ ptebShared->GdiTebBatch.HDC = (ULONG_PTR)hdcBatch; \ } \ ptebShared->GdiTebBatch.Offset += \ (pBatch->Length + sizeof(KHANDLE) - 1) & ~(sizeof(KHANDLE)-1); \ \ ptebShared->GdiBatchCount++; \ if (ptebShared->GdiBatchCount >= GdiBatchLimit) \ { \ NtGdiFlush(); \ } \ } /******************************Public*Routine******************************\ * HBRUSH CacheSelectBrush (HDC hdc, HBRUSH hbrush) * * Client side brush caching * * History: * 04-June-1995 -by- Lingyun Wang [lingyunW] * Wrote it. \**************************************************************************/ #define CACHE_SELECT_BRUSH(pDcAttr,hbrushNew,hbrushOld) \ { \ hbrushOld = 0; \ \ if (pDcAttr) \ { \ pDcAttr->ulDirty_ |= DC_BRUSH_DIRTY; \ hbrushOld = pDcAttr->hbrush; \ pDcAttr->hbrush = hbrushNew; \ } \ } /******************************Public*Routine******************************\ * CacheSelectPen * * Select a pen into DC_ATTR field of DC and set pen flag * * Arguments: * * hdc - user hdc * hpenNew - New Pen to select * * Return Value: * * Old Pen or NULL * * History: * * 25-Jan-1996 -by- Mark Enstrom [marke] * \**************************************************************************/ #define CACHE_SELECT_PEN(pdcattr,hpenNew, hpenOld) \ { \ hpenOld = 0; \ \ if (pdcattr) \ { \ pdcattr->ulDirty_ |= DC_PEN_DIRTY; \ hpenOld = pdcattr->hpen; \ pdcattr->hpen = hpenNew; \ } \ } /**************************************************************************\ * * far east * \**************************************************************************/ extern UINT guintAcp; extern UINT guintDBCScp; extern UINT fFontAssocStatus; extern WCHAR *gpwcANSICharSet; extern WCHAR *gpwcDBCSCharSet; extern BOOL gbDBCSCodePage; UINT WINAPI QueryFontAssocStatus( VOID ); DWORD FontAssocHack(DWORD,CHAR*,UINT); BOOL bComputeTextExtentDBCS(PDC_ATTR,CFONT*,LPCSTR,int,UINT,SIZE*); BOOL bComputeCharWidthsDBCS(CFONT*, UINT, UINT, ULONG, PVOID); extern BOOL IsValidDBCSRange( UINT iFirst , UINT iLast ); extern BYTE GetCurrentDefaultChar(HDC hdc); extern BOOL bSetUpUnicodeStringDBCS(UINT iFirst,UINT iLast,PUCHAR puchTmp, PWCHAR pwc, UINT uiCodePage,CHAR chDefaultChar); extern WINAPI NamedEscape(HDC,LPWSTR,int,int,LPCSTR,int,LPSTR); extern BOOL RemoteRasterizerCompatible(HANDLE hSpooler); void ConvertDxArray(UINT CP,char *pszDBCS,INT *pDxDBCS,UINT c,INT *pDxU, BOOL bPdy); #ifdef LANGPACK /**************************************************************************\ * * language packs * \**************************************************************************/ extern gbLpk; extern void InitializeLanguagePack(); typedef BOOL (* FPLPKINITIALIZE)(DWORD); typedef UINT (* FPLPKGETCHARACTERPLACEMENT) (HDC,LPCWSTR,int,int,LPGCP_RESULTSW,DWORD,INT); typedef BOOL (* FPLPKEXTEXTOUT) (HDC,INT,INT,UINT,CONST RECT*,LPCWSTR,UINT,CONST INT*,INT); typedef BOOL (* FPLPKGETTEXTEXTENTEXPOINT) (HDC, LPCWSTR, INT, INT, LPINT, LPINT, LPSIZE, FLONG, INT); typedef BOOL (* FPLPKUSEGDIWIDTHCACHE)(HDC,LPCSTR,int,LONG,BOOL); extern FPLPKGETCHARACTERPLACEMENT fpLpkGetCharacterPlacement; extern FPLPKEXTEXTOUT fpLpkExtTextOut; extern FPLPKGETCHARACTERPLACEMENT fpLpkGetCharacterPlacement; extern FPLPKGETTEXTEXTENTEXPOINT fpLpkGetTextExtentExPoint; extern FPLPKUSEGDIWIDTHCACHE fpLpkUseGDIWidthCache; #endif typedef union _BLENDULONG { BLENDFUNCTION Blend; ULONG ul; }BLENDULONG,*PBLENDULONG; BOOL bMergeSubsetFont(HDC, PVOID, ULONG, PVOID*, ULONG*, BOOL, UNIVERSAL_FONT_ID*); PUFIHASH pufihAddUFIEntry(PUFIHASH*, PUNIVERSAL_FONT_ID, ULONG, FLONG, FLONG); #define FL_UFI_SUBSET 1 BOOL bDoFontSubset(PUFIHASH, PUCHAR*, ULONG*, ULONG*); BOOL WriteFontToSpoolFile(PLDC, PUNIVERSAL_FONT_ID, FLONG); BOOL WriteSubFontToSpoolFile(PLDC, PUCHAR, ULONG, UNIVERSAL_FONT_ID*, BOOL); BOOL bAddUFIandWriteSpool(HDC,PUNIVERSAL_FONT_ID,BOOL, FLONG); VOID vFreeUFIHashTable( PUFIHASH *pUFIHashBase, FLONG fl); BOOL WriteFontDataAsEMFComment(PLDC, DWORD, PVOID, DWORD, PVOID, DWORD); // // C helper functions for working with EMFSpoolData object // (stored in the hEMFSpool field in LDC). // BOOL AllocEMFSpoolData(PLDC pldc, BOOL banding); VOID DeleteEMFSpoolData(PLDC pldc); BOOL WriteEMFSpoolData(PLDC pldc, PVOID buffer, ULONG size); BOOL FlushEMFSpoolData(PLDC pldc, DWORD pageType); #define MMAPCOPY_THRESHOLD 0x100000 // 1MB VOID CopyMemoryToMemoryMappedFile(PVOID Destination, CONST VOID *Source, DWORD Length); DWORD GetFileMappingAlignment(); DWORD GetSystemPageSize(); BOOL MirrorRgnDC(HDC hdc, HRGN hrgn, HRGN *phrgn); #define HORZSIZEP 1 #define VERTSIZEP 2 #if DBG #define EMFVALFAIL(x) DbgPrint x #else #define EMFVALFAIL(x) #endif