Leaked source code of windows server 2003
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

/******************************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