📄 emf.cpp
字号:
else
{
pCurrDM->dmCollate = DMCOLLATE_FALSE;
}
}
}
// Ignore the return values of ResetDC and SetGraphicsMode
GdiResetDCEMF(hSpoolHandle, pCurrDM);
SetGraphicsMode(hPrinterDC, GM_ADVANCED);
}
bReturn = TRUE;
return bReturn;
}
DWORD
PrintOneSideForwardEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwNumberOfPagesPerSide,
DWORD dwDrvNumberOfPagesPerSide,
DWORD dwNupBorderFlags,
BOOL bDuplex,
DWORD dwOptimization,
DWORD dwPageNumber,
DWORD dwJobNumberOfCopies,
LPBOOL pbComplete,
LPDEVMODE pDevmode)
/*++
Function Description: PrintOneSideForwardEMF plays the next physical page in the same order
as the spool file.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwNumberOfPagesPerSide -- number of pages to be printed per side by the print processor
dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
dwNupBorderFlags -- border printing options for nup
bDuplex -- flag to indicate duplex printing
dwOptimization -- optimization flags
dwPageNumber -- pointer to the starting page number
pbComplete -- pointer to the flag to indicate completion
pDevmode -- devmode with resolution settings
Return Values: Last Page Number if successful
0 on job completion (pbReturn set to TRUE) and
on failure (pbReturn remains FALSE)
--*/
{
DWORD dwPageIndex, dwPageType;
DWORD dwReturn = 0;
LPDEVMODEW pCurrDM;
HANDLE hEMF = NULL;
DWORD dwSides;
BOOL bNewDevmode;
DWORD cPagesToPlay;
DWORD dwAngle;
INT dmOrientation = pDevmode->dmOrientation;
// set the number of sides on this page;
dwSides = bDuplex ? 2 : 1;
*pbComplete = FALSE;
for ( ; dwSides && !*pbComplete ; --dwSides) {
// loop for a single side
for (dwPageIndex = 1;
dwPageIndex <= dwNumberOfPagesPerSide;
++dwPageIndex, ++dwPageNumber) {
if (!(hEMF = GdiGetPageHandle(hSpoolHandle,
dwPageNumber,
&dwPageType))) {
if (GetLastError() == ERROR_NO_MORE_ITEMS) {
// End of the print job
*pbComplete = TRUE;
break;
}
ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
dwAngle = EMF_DEGREE_90;
if (dwPageIndex == 1)
{
// Process new devmodes in the spool file that appear before this page
if (!ResetDCForNewDevmode(hSpoolHandle,
hPrinterDC,
dwPageNumber,
(dwPageIndex != 1),
dwOptimization,
&bNewDevmode,
pDevmode,
&pCurrDM)) {
goto CleanUp;
}
if (pCurrDM)
dmOrientation = pCurrDM->dmOrientation;
}
// in case of orientation switch we need to keep track of what
// we started with and what it is now
else if (dwNumberOfPagesPerSide > 1)
{
if (GdiGetDevmodeForPagePvt(hSpoolHandle,
dwPageNumber,
&pCurrDM,
NULL))
{
if (pCurrDM && pCurrDM->dmOrientation != dmOrientation)
{
dwAngle = EMF_DEGREE_SWAP | EMF_DEGREE_90;
}
}
}
// Call StartPage for each new page
if ((dwPageIndex == 1) &&
!GdiStartPageEMF(hSpoolHandle)) {
ODS(("StartPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
if (!PlayEMFPage(hSpoolHandle,
hPrinterDC,
hEMF,
dwNumberOfPagesPerSide,
dwPageNumber,
dwPageIndex,
dwNupBorderFlags,
dwAngle)) {
ODS(("PlayEMFPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
//
// Explaination of the scinario set for the conditions on
// dwPageIndex1 , pbComplete and bDuplex.
// N.B. we are naming them cond.1 and cond.2
// dwPageIndex!=1 pbComplete bDuplex Condition
// 0 0 0 None
// 0 0 1 None
// 0 1 0 None
// 0 1 1 Cond2 on Second Side i.e. dwsides==1
// 1 0 0 Cond1
// 1 0 1 Cond1
// 1 1 0 Cond1
// 1 1 1 Cond1 & Cond2 on First Side i.e. dwsides==2
//
// cond.1
if (dwPageIndex != 1) {
// Call EndPage if we played any pages
if (!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
ODS(("EndPage failed\n"));
*pbComplete = FALSE;
goto CleanUp;
}
}
// cond.2
// play empty page on the back of duplex
if (*pbComplete && bDuplex && dwDrvNumberOfPagesPerSide==1) {
ODS(("PCL or PS with no N-up\n"));
//
// Checking dwsides against 2 or 1.
// depends on whether it is n-up or not.
//
if (((dwPageIndex!=1)?(dwSides==2):(dwSides==1))) {
if (!GdiStartPageEMF(hSpoolHandle) ||
!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
ODS(("EndPage failed\n"));
*pbComplete = FALSE;
goto CleanUp;
}
}
}
}
if (*pbComplete &&
dwNumberOfPagesPerSide==1 &&
dwDrvNumberOfPagesPerSide!=1 &&
dwJobNumberOfCopies!=1)
{
cPagesToPlay = dwDrvNumberOfPagesPerSide * (bDuplex ? 2 : 1);
if ((dwPageNumber-1) % cPagesToPlay)
{
//
// Number of pages played on last physical page
//
cPagesToPlay = cPagesToPlay - ((dwPageNumber-1) % cPagesToPlay);
ODS(("\nPS with N-up!\nMust fill in %u pages\n", cPagesToPlay));
for (;cPagesToPlay;cPagesToPlay--)
{
if (!GdiStartPageEMF(hSpoolHandle) || !GdiEndPageEMF(hSpoolHandle, dwOptimization))
{
ODS(("EndPage failed\n"));
goto CleanUp;
}
}
}
}
if (!(*pbComplete)) dwReturn = dwPageNumber;
CleanUp:
return dwReturn;
}
BOOL
PrintForwardEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwNumberOfPagesPerSide,
DWORD dwDrvNumberOfPagesPerSide,
DWORD dwNupBorderFlags,
DWORD dwJobNumberOfCopies,
DWORD dwDrvNumberOfCopies,
BOOL bCollate,
BOOL bDuplex,
DWORD dwOptimization,
LPDEVMODEW pDevmode,
PPRINTPROCESSORDATA pData)
/*++
Function Description: PrintForwardEMF plays the EMF files in the order in which they
were spooled.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwNumberOfPagesPerSide -- number of pages to be printed per side by the print processor
dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
dwNupBorderFlags -- border printing options for nup
dwJobNumberOfCopies -- number of copies of the job to be printed
dwDrvNumberOfCopies -- number of copies that the driver can print
bCollate -- flag for collating the copies
bDuplex -- flag for duplex printing
dwOptimization -- optimization flags
pDevmode -- pointer to devmode for changing the copy count
pData -- needed for status and the handle of the event: pause, resume etc.
Return Values: TRUE if successful
FALSE otherwise
--*/
{
DWORD dwLastPageNumber = 1,dwPageNumber,dwRemainingCopies;
BOOL bReturn = FALSE;
// Keep printing as long as the spool file contains EMF handles.
while (dwLastPageNumber) {
//
// If the print processor is paused, wait for it to be resumed
//
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
WaitForSingleObject(pData->semPaused, INFINITE);
}
dwPageNumber = dwLastPageNumber;
if (bCollate) {
dwLastPageNumber = PrintOneSideForwardEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwDrvNumberOfPagesPerSide,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwPageNumber,
dwJobNumberOfCopies,
&bReturn,
pDevmode);
} else {
dwRemainingCopies = dwJobNumberOfCopies;
while (dwRemainingCopies) {
if (dwRemainingCopies <= dwDrvNumberOfCopies) {
SetDrvCopies(hPrinterDC, pDevmode, dwRemainingCopies);
dwRemainingCopies = 0;
} else {
SetDrvCopies(hPrinterDC, pDevmode, dwDrvNumberOfCopies);
dwRemainingCopies -= dwDrvNumberOfCopies;
}
if (!(dwLastPageNumber = PrintOneSideForwardEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwDrvNumberOfPagesPerSide,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwPageNumber,
dwJobNumberOfCopies,
&bReturn,
pDevmode)) &&
!bReturn) {
goto CleanUp;
}
}
}
}
CleanUp:
return bReturn;
}
BOOL
PrintOneSideReverseForDriverEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwDrvNumberOfPagesPerSide,
DWORD dwTotalNumberOfPages,
DWORD dwNupBorderFlags,
BOOL bDuplex,
DWORD dwOptimization,
DWORD dwPageNumber,
LPDEVMODE pDevmode)
/*++
Function Description: PrintOneSideReverseForDriverEMF plays the EMF pages on the next
physical page, in the reverse order for the driver which does the
Nup transformations.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
dwTotalNumberOfPages -- total number of pages in the document
dwNupBorderFlags -- border printing options for nup
bDuplex -- flag to indicate duplex printing
dwOptimization -- optimization flags
dwPageNumber -- page number to start the side
pDevmode -- devmode with resolution settings
Return Values: TRUE if successful
FALSE otherwise
--*/
{
DWORD dwPageIndex, dwPageType, dwSides;
BOOL bReturn = FALSE, bNewDevmode,BeSmart;
HANDLE hEMF = NULL;
DWORD dwLimit;
dwSides = bDuplex ? 2 : 1;
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -