📄 emf.c
字号:
DWORD cPagesToPlay;
// 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;
}
// Process new devmodes in the spool file that appear before this page
if (!ResetDCForNewDevmode(hSpoolHandle,
hPrinterDC,
dwPageNumber,
(dwPageIndex != 1),
dwOptimization,
&bNewDevmode,
pDevmode)) {
goto CleanUp;
}
// Reset page index if new page was started
if (bNewDevmode) {
dwPageIndex = 1;
}
// 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,
EMF_DEGREE_90)) {
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 &&
bDuplex &&
(dwPageNumber-1)%(2*dwDrvNumberOfPagesPerSide))
{
//
// Number of pages played on last phisical page
//
cPagesToPlay = 2*dwDrvNumberOfPagesPerSide - (dwPageNumber-1)%(2*dwDrvNumberOfPagesPerSide);
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,dwPageIndex,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,
&bReturn,
pDevmode);
} else {
dwRemainingCopies = dwJobNumberOfCopies;
while (dwRemainingCopies) {
if (dwRemainingCopies <= dwDrvNumberOfCopies) {
SetDrvCopies(hPrinterDC, pDevmode, dwRemainingCopies);
dwRemainingCopies = 0;
} else {
SetDrvCopies(hPrinterDC, pDevmode, dwDrvNumberOfCopies);
dwRemainingCopies -= dwDrvNumberOfCopies;
}
//
// If the print processor is paused, wait for it to be resumed
//
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
WaitForSingleObject(pData->semPaused, INFINITE);
}
if (!(dwLastPageNumber = PrintOneSideForwardEMF(hSpoolHandle,
hPrinterDC,
dwNumberOfPagesPerSide,
dwDrvNumberOfPagesPerSide,
dwNupBorderFlags,
bDuplex,
dwOptimization,
dwPageNumber,
&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;
LPDEVMODEW pLastDM,pCurrDM;
HANDLE hEMF = NULL;
DWORD dwLimit;
dwSides = bDuplex ? 2 : 1;
//
// 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) &&
(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)) {
}
}
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -