📄 emf.cpp
字号:
// If the document will fit on one phisical page, then this variable will prevent
// the printer from playing extra pages just to fill in one phisical page
// The exception is when the pages fit on a single phisical page, but they must
// be collated. Then because of design, the printer will also draw borders for the
// empty pages which are played so that the page gets ejected.
//
BeSmart = (dwTotalNumberOfPages<=dwDrvNumberOfPagesPerSide) &&
IS_DMSIZE_VALID(pDevmode, dmCollate) &&
(pDevmode->dmCollate != DMCOLLATE_TRUE);
for (; dwSides; --dwSides) {
// This loop may play some empty pages in the last side, since the
// driver is doing nup and it does not keep count of the page numbers
//
dwPageIndex=BeSmart?dwPageNumber:1;
dwLimit =BeSmart?dwTotalNumberOfPages:dwDrvNumberOfPagesPerSide;
for (;dwPageIndex<=dwLimit; ++dwPageIndex,++dwPageNumber) {
if (BeSmart || dwPageNumber <= dwTotalNumberOfPages) {
if (!(hEMF = GdiGetPageHandle(hSpoolHandle,
dwPageNumber,
&dwPageType))) {
ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
// Process new devmodes in the spoolfile
if (!ResetDCForNewDevmode(hSpoolHandle,
hPrinterDC,
dwPageNumber,
FALSE,
dwOptimization,
&bNewDevmode,
pDevmode,
NULL)) {
}
}
if (!GdiStartPageEMF(hSpoolHandle)) {
ODS(("StartPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
if (BeSmart || dwPageNumber <= dwTotalNumberOfPages) {
if (!PlayEMFPage(hSpoolHandle,
hPrinterDC,
hEMF,
1,
dwPageNumber,
1,
dwNupBorderFlags,
EMF_DEGREE_90)) {
ODS(("PlayEMFPage failed\n"));
goto CleanUp;
}
}
if (!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
ODS(("EndPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintReverseForDriverEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwDrvNumberOfPagesPerSide,
DWORD dwTotalNumberOfPages,
DWORD dwNupBorderFlags,
DWORD dwJobNumberOfCopies,
DWORD dwDrvNumberOfCopies,
BOOL bCollate,
BOOL bDuplex,
BOOL bOdd,
DWORD dwOptimization,
LPDEVMODEW pDevmode,
PPAGE_NUMBER pHead,
PPRINTPROCESSORDATA pData)
/*++
Function Description: PrintReverseForDriverEMF plays the EMF pages 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
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 to indicate duplex printing
bOdd -- flag to indicate odd number of sides to print
dwOptimization -- optimization flags
pDevmode -- pointer to devmode for changing the copy count
pHead -- pointer to a linked list containing the starting
page numbers for each of the sides
pData -- needed for status and the handle of the event: pause, resume etc.
Return Values: TRUE if successful
FALSE otherwise
--*/
{
DWORD dwPageNumber,dwRemainingCopies;
BOOL bReturn = FALSE;
// select the correct page for duplex printing
if (bDuplex && !bOdd) {
if (pHead) {
pHead = pHead->pNext;
} else {
bReturn = TRUE;
goto CleanUp;
}
}
// play the sides in reverse order
while (pHead) {
//
// If the print processor is paused, wait for it to be resumed
//
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
WaitForSingleObject(pData->semPaused, INFINITE);
}
// set the page number
dwPageNumber = pHead->dwPageNumber;
if (bCollate) {
if (!PrintOneSideReverseForDriverEMF(hSpoolHandle,
hPrinterDC,
dwDrvNumberOfPagesPerSide,
dwTotalNumberOfPages,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwPageNumber,
pDevmode)) {
goto CleanUp;
}
} else {
dwRemainingCopies = dwJobNumberOfCopies;
while (dwRemainingCopies) {
if (dwRemainingCopies <= dwDrvNumberOfCopies) {
SetDrvCopies(hPrinterDC, pDevmode, dwRemainingCopies);
dwRemainingCopies = 0;
} else {
SetDrvCopies(hPrinterDC, pDevmode, dwDrvNumberOfCopies);
dwRemainingCopies -= dwDrvNumberOfCopies;
}
if (!PrintOneSideReverseForDriverEMF(hSpoolHandle,
hPrinterDC,
dwDrvNumberOfPagesPerSide,
dwTotalNumberOfPages,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwPageNumber,
pDevmode)) {
goto CleanUp;
}
}
}
pHead = pHead->pNext;
// go to the next page for duplex printing
if (bDuplex && pHead) {
pHead = pHead->pNext;
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintOneSideReverseEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwNumberOfPagesPerSide,
DWORD dwNupBorderFlags,
BOOL bDuplex,
DWORD dwOptimization,
DWORD dwStartPage1,
DWORD dwEndPage1,
DWORD dwStartPage2,
DWORD dwEndPage2,
LPDEVMODE pDevmode)
/*++
Function Description: PrintOneSideReverseEMF plays the EMF pages for the next physical page.
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
dwNupBorderFlags -- border printing options for nup
bDuplex -- flag to indicate duplex printing
dwOptimization -- optimization flags
dwStartPage1 -- page number of the first EMF page on 1st side
dwEndPage1 -- page number of the last EMF page on 1st side
dwStartPage2 -- page number of the first EMF page on 2nd side
dwEndPage2 -- page number of the last EMF page on 2nd side
pDevmode -- devmode with resolution settings
Return Values: TRUE if successful
FALSE otherwise
--*/
{
DWORD dwPageNumber, dwPageIndex, dwPageType;
BOOL bReturn = FALSE, bNewDevmode;
LPDEVMODEW pCurrDM;
HANDLE hEMF = NULL;
DWORD dwEndPage, dwStartPage, dwSides, dwAngle;
INT dmOrientation = pDevmode->dmOrientation;
for (dwSides = bDuplex ? 2 : 1;
dwSides;
--dwSides) {
if (bDuplex && (dwSides == 1)) {
dwStartPage = dwStartPage2;
dwEndPage = dwEndPage2;
} else {
dwStartPage = dwStartPage1;
dwEndPage = dwEndPage1;
}
for (dwPageNumber = dwStartPage, dwPageIndex = 1;
dwPageNumber <= dwEndPage;
++dwPageNumber, ++dwPageIndex) {
if (!(hEMF = GdiGetPageHandle(hSpoolHandle,
dwPageNumber,
&dwPageType))) {
ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
dwAngle = EMF_DEGREE_90;
if (dwPageIndex == 1) {
// Process devmodes in the spool file and call StartPage
if (!ResetDCForNewDevmode(hSpoolHandle,
hPrinterDC,
dwPageNumber,
FALSE,
dwOptimization,
&bNewDevmode,
pDevmode,
&pCurrDM) ||
!GdiStartPageEMF(hSpoolHandle)) {
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;
}
}
}
if (!PlayEMFPage(hSpoolHandle,
hPrinterDC,
hEMF,
dwNumberOfPagesPerSide,
dwPageNumber,
dwPageIndex,
dwNupBorderFlags,
dwAngle)) {
ODS(("PlayEMFPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
if ((dwPageIndex == 1) && !GdiStartPageEMF(hSpoolHandle)) {
ODS(("StartPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
if (!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
ODS(("EndPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
goto CleanUp;
}
}
bReturn = TRUE;
CleanUp:
return bReturn;
}
BOOL
PrintReverseEMF(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwTotalNumberOfPages,
DWORD dwNumberOfPagesPerSide,
DWORD dwNupBorderFlags,
DWORD dwJobNumberOfCopies,
DWORD dwDrvNumberOfCopies,
BOOL bCollate,
BOOL bDuplex,
BOOL bOdd,
DWORD dwOptimization,
LPDEVMODEW pDevmode,
PPAGE_NUMBER pHead,
PPRINTPROCESSORDATA pData)
/*++
Function Description: PrintReverseEMF plays the EMF pages in the reverse order and also
performs nup transformations.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
dwTotalNumberOfPages -- number of pages in the document
dwNumberOfPagesPerSide -- number of pages to be printed per side by the print
processor
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 to indicate duplex printing
bOdd -- flag to indicate odd number of sides to print
dwOptimization -- optimization flags
pDevmode -- pointer to devmode for changing the copy count
pHead -- pointer to a linked list containing the starting
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -