You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1539 lines
60 KiB
1539 lines
60 KiB
/******************************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
|