📄 emf.c
字号:
rectDocument->bottom -= (LONG) (dYbottom * lYNewPhyPage);
}
if (xResolution!=yResolution)
{
rectDocument->left = rectDocument->left / yResolution;
rectDocument->right = rectDocument->right / yResolution;
rectDocument->top = rectDocument->top / xResolution;
rectDocument->bottom = rectDocument->bottom / xResolution;
}
return;
}
BOOL
PlayEMFPage(
HANDLE hSpoolHandle,
HDC hPrinterDC,
HANDLE hEMF,
DWORD dwNumberOfPagesPerSide,
DWORD dwPageNumber,
DWORD dwPageIndex,
DWORD dwNupBorderFlags,
DWORD dwAngle)
/*++
Function Description: PlayEMFPage plays the EMF in the appropriate rectangle. It performs
the required scaling, rotation and translation.
Parameters: hSpoolHandle -- handle the spool file handle
hPrinterDC -- handle to the printer device context
hEMF -- handle to the contents of the page in the spool file
dwNumberOfPagesPerSide -- number of pages to be printed per side
dwPageNumber -- page number in the document
dwPageIndex -- page number in the side. (1 based)
dwNupBorderFlags -- border printing options for nup
dwAngle -- angle for rotation (if neccesary)
Return Values: TRUE if successful
FALSE otherwise
--*/
{
BOOL bReturn = FALSE, bRotate;
RECT rectDocument, rectPrinter, rectBorder = {-1, -1, -1, -1};
RECT *prectClip = NULL;
XFORM TransXForm = {1, 0, 0, 1, 0, 0}, RotateXForm = {0, -1, 1, 0, 0, 0};
HPEN hPen;
HANDLE hFormEMF;
DWORD dwPageType,dwFormPage;
// Compute the rectangle for one page.
GetPageCoordinatesForNUp(hPrinterDC,
&rectDocument,
&rectBorder,
dwNumberOfPagesPerSide,
dwPageIndex,
dwNupBorderFlags,
&bRotate);
if (dwAngle == EMF_DEGREE_270) {
RotateXForm.eM12 = 1;
RotateXForm.eM21 = -1;
} // EMF_DEGREE_90 case is the initialization
if (bRotate) {
rectPrinter.top = 0;
rectPrinter.bottom = rectDocument.right - rectDocument.left;
rectPrinter.left = 0;
rectPrinter.right = rectDocument.bottom - rectDocument.top;
// Set the translation matrix
if (dwAngle == EMF_DEGREE_270) {
TransXForm.eDx = (float) rectDocument.right;
TransXForm.eDy = (float) rectDocument.top;
} else {
// EMF_DEGREE_90
TransXForm.eDx = (float) rectDocument.left;
TransXForm.eDy = (float) rectDocument.bottom;
}
// Set the transformation matrix
if (!SetWorldTransform(hPrinterDC, &RotateXForm) ||
!ModifyWorldTransform(hPrinterDC, &TransXForm, MWT_RIGHTMULTIPLY)) {
ODS(("Setting transformation matrix failed\n"));
goto CleanUp;
}
}
// Add clipping for Nup
if (dwNumberOfPagesPerSide != 1) {
prectClip = &rectDocument;
}
// Print the page.
if (bRotate) {
GdiPlayPageEMF(hSpoolHandle, hEMF, &rectPrinter, &rectBorder, prectClip);
} else {
GdiPlayPageEMF(hSpoolHandle, hEMF, &rectDocument, &rectBorder, prectClip);
}
bReturn = TRUE;
CleanUp:
if (!ModifyWorldTransform(hPrinterDC, NULL, MWT_IDENTITY)) {
ODS(("Setting Identity Transformation failed\n"));
bReturn = FALSE;
}
return bReturn;
}
BOOL
SetDrvCopies(
HDC hPrinterDC,
LPDEVMODEW pDevmode,
DWORD dwNumberOfCopies)
/*++
Function Description: SetDrvCopies sets the dmCopies field in pDevmode and resets
hPrinterDC with this devmode
Parameters: hPrinterDC -- handle to the printer device context
pDevmode -- pointer to devmode
dwNumberOfCopies -- value for dmCopies
Return Values: TRUE if successful
FALSE otherwise
--*/
{
BOOL bReturn;
DWORD dmFields;
if ((pDevmode->dmFields & DM_COPIES) &&
(pDevmode->dmCopies == (short) dwNumberOfCopies)) {
return TRUE;
}
// Save the old fields structure
dmFields = pDevmode->dmFields;
pDevmode->dmFields |= DM_COPIES;
pDevmode->dmCopies = (short) dwNumberOfCopies;
if (!ResetDC(hPrinterDC, pDevmode)) {
bReturn = FALSE;
} else {
bReturn = TRUE;
}
// Restore the fields structure
pDevmode->dmFields = dmFields;
if (!SetGraphicsMode(hPrinterDC,GM_ADVANCED)) {
ODS(("Setting graphics mode failed\n"));
bReturn = FALSE;
}
return bReturn;
}
BOOL
DifferentDevmodes(
LPDEVMODE pDevmode1,
LPDEVMODE pDevmode2
)
/*++
Function Description: Compares the devmodes for differences other than dmTTOption
Parameters: pDevmode1 - devmode 1
pDevmode2 - devmode 2
Return Values: TRUE if different ; FALSE otherwise
--*/
{
DWORD dwSize1, dwSize2, dwTTOffset, dwSpecOffset, dwLogOffset;
// Same pointers are the same devmode
if (pDevmode1 == pDevmode2) {
return FALSE;
}
// Check for Null devmodes
if (!pDevmode1 || !pDevmode2) {
return TRUE;
}
dwSize1 = pDevmode1->dmSize + pDevmode1->dmDriverExtra;
dwSize2 = pDevmode2->dmSize + pDevmode2->dmDriverExtra;
// Compare devmode sizes
if (dwSize1 != dwSize2) {
return TRUE;
}
dwTTOffset = FIELD_OFFSET(DEVMODE, dmTTOption);
dwSpecOffset = FIELD_OFFSET(DEVMODE, dmSpecVersion);
dwLogOffset = FIELD_OFFSET(DEVMODE, dmLogPixels);
if (wcscmp(pDevmode1->dmDeviceName,
pDevmode2->dmDeviceName)) {
// device names are different
return TRUE;
}
if (dwTTOffset < dwSpecOffset ||
dwSize1 < dwLogOffset) {
// incorrent devmode offsets
return TRUE;
}
if (memcmp((LPBYTE) pDevmode1 + dwSpecOffset,
(LPBYTE) pDevmode2 + dwSpecOffset,
dwTTOffset - dwSpecOffset)) {
// Front half is different
return TRUE;
}
// Ignore the dmTTOption setting.
if ((pDevmode1->dmCollate != pDevmode2->dmCollate) ||
wcscmp(pDevmode1->dmFormName, pDevmode2->dmFormName)) {
// form name or collate option is different
return TRUE;
}
if (memcmp((LPBYTE) pDevmode1 + dwLogOffset,
(LPBYTE) pDevmode2 + dwLogOffset,
dwSize1 - dwLogOffset)) {
// Back half is different
return TRUE;
}
return FALSE;
}
BOOL
ResetDCForNewDevmode(
HANDLE hSpoolHandle,
HDC hPrinterDC,
DWORD dwPageNumber,
BOOL bInsidePage,
DWORD dwOptimization,
LPBOOL pbNewDevmode,
LPDEVMODE pDevmode
)
/*++
Function Description: Determines if the devmode for the page is different from the
current devmode for the printer dc and resets the dc if necessary.
The parameters allow dmTTOption to be ignored in devmode comparison.
Parameters: hSpoolHandle - spool file handle
hPrinterDC - printer dc
dwPageNumber - page number before which we search for the devmode
bInsidePage - flag to ignore changes in TT options and call EndPage
before ResetDC
dwOptimization - optimization flags
pbNewDevmode - pointer to flag to indicate if ResetDC was called
pDevmode - devmode containing changed resolution settings
Return Values: TRUE if successful; FALSE otherwise
--*/
{
BOOL bReturn = FALSE;
LPDEVMODE pLastDM, pCurrDM;
// Initialize OUT parameters
*pbNewDevmode = FALSE;
// Get the devmode just before the page
if (!GdiGetDevmodeForPage(hSpoolHandle,
dwPageNumber,
&pCurrDM,
&pLastDM)) {
ODS(("GdiGetDevmodeForPage failed\n"));
return bReturn;
}
// Check if the devmodes are different
if (pLastDM != pCurrDM) {
// If the pointers are different the devmodes are always different
if (!bInsidePage ||
DifferentDevmodes(pLastDM, pCurrDM)) {
*pbNewDevmode = TRUE;
}
}
// Call ResetDC on the hPrinterDC if necessary
if (*pbNewDevmode) {
if (bInsidePage &&
!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
ODS(("EndPage failed\n"));
return bReturn;
}
if (pCurrDM) {
pCurrDM->dmPrintQuality = pDevmode->dmPrintQuality;
pCurrDM->dmYResolution = pDevmode->dmYResolution;
}
// 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,
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 pLastDM, pCurrDM;
HANDLE hEMF = NULL;
DWORD dwSides;
BOOL bNewDevmode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -