⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emf.c

📁 用delphi开发的有关打印的驱动实例; LIBRARY genprint EXPORTS EnumPrintProcessorDatatypesW OpenPrintProc
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c) 1990-1998  Microsoft Corporation
All rights reserved


Abstract:

    Routines to facilitate printing of EMF jobs.

--*/

#include "local.h"
#include "stddef.h"
#include <windef.h>
#include <messages.h>


#include <winppi.h>

#define EMF_DUP_NONE 0
#define EMF_DUP_VERT 1
#define EMF_DUP_HORZ 2

#define EMF_DEGREE_90  1
#define EMF_DEGREE_270 2


//   PAGE_NUMBER is used to save a list of the page numbers to start new sides while
//   Reverse Printing.

typedef struct _PAGE_NUMBER {
    struct _PAGE_NUMBER *pNext;
    DWORD  dwPageNumber;
} PAGE_NUMBER, *PPAGE_NUMBER;

typedef struct _UpdateRect {
        double  top;
        double  bottom;
        double  left;
        double  right;
}  UpdateRect;

// The update factors for the different nup options. These factors when multiplied
// with the horizontal and vertical resolutions give the coordinates for the rectangle
// where the EMF page is to be played.

UpdateRect URect21[] = {{0, 0.5, 0, 1},
                        {0.5, 1, 0, 1}};

UpdateRect URect21R[] = {{0.5, 1, 0, 1},
                         {0, 0.5, 0, 1}};

UpdateRect URect22[] = {{0, 1, 0, 0.5},
                        {0, 1, 0.5, 1}};

UpdateRect URect4[] = {{0, 0.5, 0, 0.5},
                       {0, 0.5, 0.5, 1},
                       {0.5, 1, 0, 0.5},
                       {0.5, 1, 0.5, 1}};

UpdateRect URect61[] = {{0, 1.0/3.0, 0, 0.5},
                        {0, 1.0/3.0, 0.5, 1},
                        {1.0/3.0, 2.0/3.0, 0, 0.5},
                        {1.0/3.0, 2.0/3.0, 0.5, 1},
                        {2.0/3.0, 1, 0, 0.5},
                        {2.0/3.0, 1, 0.5, 1}};

UpdateRect URect61R[] = {{2.0/3.0, 1, 0, 0.5},
                         {1.0/3.0, 2.0/3.0, 0, 0.5},
                         {0, 1.0/3.0, 0, 0.5},
                         {2.0/3.0, 1, 0.5, 1},
                         {1.0/3.0, 2.0/3.0, 0.5, 1},
                         {0, 1.0/3.0, 0.5, 1}};

UpdateRect URect62[]  = {{0, 0.5, 0, 1.0/3.0},
                         {0, 0.5, 1.0/3.0, 2.0/3.0},
                         {0, 0.5, 2.0/3.0, 1},
                         {0.5, 1, 0, 1.0/3.0},
                         {0.5, 1, 1.0/3.0, 2.0/3.0},
                         {0.5, 1, 2.0/3.0, 1}};

UpdateRect URect62R[] = {{0.5, 1, 0, 1.0/3.0},
                         {0, 0.5, 0, 1.0/3.0},
                         {0.5, 1, 1.0/3.0, 2.0/3.0},
                         {0, 0.5, 1.0/3.0, 2.0/3.0},
                         {0.5, 1, 2.0/3.0, 1},
                         {0, 0.5, 2.0/3.0, 1}};

UpdateRect URect9[] = {{0, 1.0/3.0, 0, 1.0/3.0},
                       {0, 1.0/3.0, 1.0/3.0, 2.0/3.0},
                       {0, 1.0/3.0, 2.0/3.0, 1},
                       {1.0/3.0, 2.0/3.0, 0, 1.0/3.0},
                       {1.0/3.0, 2.0/3.0, 1.0/3.0, 2.0/3.0},
                       {1.0/3.0, 2.0/3.0, 2.0/3.0, 1},
                       {2.0/3.0, 1, 0, 1.0/3.0},
                       {2.0/3.0, 1, 1.0/3.0, 2.0/3.0},
                       {2.0/3.0, 1, 2.0/3.0, 1}};

UpdateRect URect16[] = {{0, 0.25, 0, 0.25},
                        {0, 0.25, 0.25, 0.5},
                        {0, 0.25, 0.5, 0.75},
                        {0, 0.25, 0.75, 1},
                        {0.25, 0.5, 0, 0.25},
                        {0.25, 0.5, 0.25, 0.5},
                        {0.25, 0.5, 0.5, 0.75},
                        {0.25, 0.5, 0.75, 1},
                        {0.5, 0.75, 0, 0.25},
                        {0.5, 0.75, 0.25, 0.5},
                        {0.5, 0.75, 0.5, 0.75},
                        {0.5, 0.75, 0.75, 1},
                        {0.75, 1, 0, 0.25},
                        {0.75, 1, 0.25, 0.5},
                        {0.75, 1, 0.5, 0.75},
                        {0.75, 1, 0.75, 1}};

BOOL
ValidNumberForNUp(
    DWORD  dwPages)

/*++
Function Description: Checks if the number of pages printed on a single side is Valid.

Parameters: dwPages - Number of pages printed on a single side

Return Values: TRUE if (dwPages = 1|2|4|6|9|16)
               FALSE otherwise.
--*/

{

    return ((dwPages == 1) || (dwPages == 2) || (dwPages == 4) ||
            (dwPages == 6) || (dwPages == 9) || (dwPages == 16));
}

VOID
GetPageCoordinatesForNUp(
    HDC    hPrinterDC,
    RECT   *rectDocument,
    RECT   *rectBorder,
    DWORD  dwTotalNumberOfPages,
    UINT   uCurrentPageNumber,
    DWORD  dwNupBorderFlags,
    LPBOOL pbRotate
    )

/*++
Function Description: GetPageCoordinatesForNUp computes the rectangle on the Page where the
                      EMF file is to be played. It also determines if the picture is to
                      rotated.

Parameters:  hPrinterDC           - Printer Device Context
             *rectDocument        - pointer to RECT where the coordinates to play the
                                     page will be returned.
             *rectBorder          - pointer to RECT where the page borders are to drawn.
             dwTotalNumberOfPages - Total number of pages on 1 side.
             uCurrentPageNumber   - 1 based page number on the side.
             dwNupBorderFlags     - flags to draw border along logical pages.
             pbRotate             - pointer to BOOL which indicates if the picture must be
                                    rotated.

Return Values:  NONE.
--*/

{

    UpdateRect  *URect;
    LONG        lXPrintPage,lYPrintPage,lXPhyPage,lYPhyPage,lXFrame,lYFrame,ltemp,ldX,ldY;
    LONG        lXNewPhyPage,lYNewPhyPage,lXOffset,lYOffset,lNumRowCol,lRowIndex,lColIndex;
    double      dXleft,dXright,dYtop,dYbottom;
    LONG        xResolution = GetDeviceCaps(hPrinterDC, LOGPIXELSX);
    LONG        yResolution = GetDeviceCaps(hPrinterDC, LOGPIXELSY);

    // Get the 0-based array index for the current page

    uCurrentPageNumber = uCurrentPageNumber - 1;

    if (dwTotalNumberOfPages==1 || xResolution==yResolution)
    {
        xResolution = yResolution = 1;
    }

    rectDocument->top = rectDocument->bottom = lYPrintPage = (GetDeviceCaps(hPrinterDC, DESKTOPVERTRES)-1) * xResolution;
    rectDocument->left = rectDocument->right = lXPrintPage = (GetDeviceCaps(hPrinterDC, DESKTOPHORZRES)-1) * yResolution;

    lXPhyPage = GetDeviceCaps(hPrinterDC, PHYSICALWIDTH)  * yResolution;
    lYPhyPage = GetDeviceCaps(hPrinterDC, PHYSICALHEIGHT) * xResolution;

    *pbRotate = FALSE;

    // Select the array containing the update factors

    switch (dwTotalNumberOfPages) {

    case 1: rectDocument->top = rectDocument->left = 0;
            rectDocument->right += 1;
            rectDocument->bottom += 1;
            return;

    case 2: if (lXPrintPage > lYPrintPage) {  // cut vertically
                URect = URect22;
                lXFrame = (LONG) (lXPrintPage / 2.0);
                lYFrame = lYPrintPage;
            } else {                          // cut horizontally
                URect = URect21;
                lYFrame = (LONG) (lYPrintPage / 2.0);
                lXFrame = lXPrintPage;
            }
            break;


    case 4: URect = URect4;
            lXFrame = (LONG) (lXPrintPage / 2.0);
            lYFrame = (LONG) (lYPrintPage / 2.0);
            break;

    case 6: if (lXPrintPage > lYPrintPage) {  // cut vertically twice
                URect = URect62;
                lXFrame = (LONG) (lXPrintPage / 3.0);
                lYFrame = (LONG) (lYPrintPage / 2.0);
            } else {                          // cut horizontally twice
                URect = URect61;
                lYFrame = (LONG) (lYPrintPage / 3.0);
                lXFrame = (LONG) (lXPrintPage / 2.0);
            }
            break;

    case 9: URect = URect9;
            lXFrame = (LONG) (lXPrintPage / 3.0);
            lYFrame = (LONG) (lYPrintPage / 3.0);
            break;

    case 16: URect = URect16;
             lXFrame = (LONG) (lXPrintPage / 4.0);
             lYFrame = (LONG) (lYPrintPage / 4.0);
             break;

    default: // Should Not Occur.
             return;
    }

    // Set the flag if the picture has to be rotated
    *pbRotate = !((lXPhyPage >= lYPhyPage) && (lXFrame >= lYFrame)) &&
                !((lXPhyPage < lYPhyPage) && (lXFrame < lYFrame));


    // If the picture is to be rotated, modify the rectangle selected.

    if ((dwTotalNumberOfPages == 2) || (dwTotalNumberOfPages == 6)) {

       if (*pbRotate) {
          switch (dwTotalNumberOfPages) {

          case 2: if (lXPrintPage <= lYPrintPage) {
                      URect = URect21R;
                  } // URect22 = URect22R
                  break;

          case 6: if (lXPrintPage <= lYPrintPage) {
                      URect = URect61R;
                  } else {
                      URect = URect62R;
                  }
                  break;
          }
       }

    } else {

       if (*pbRotate) {

          // get the number of rows/columns. switch is faster than sqrt.
          switch (dwTotalNumberOfPages) {

          case 4: lNumRowCol = 2;
                  break;
          case 9: lNumRowCol = 3;
                  break;
          case 16: lNumRowCol = 4;
                  break;
          }

          lRowIndex  = (LONG) (uCurrentPageNumber / lNumRowCol);
          lColIndex  = (LONG) (uCurrentPageNumber % lNumRowCol);

          uCurrentPageNumber = (lNumRowCol - 1 - lColIndex) * lNumRowCol + lRowIndex;
       }

    }

    // Update the Page Coordinates.

    rectDocument->top    = (LONG) (rectDocument->top    * URect[uCurrentPageNumber].top);
    rectDocument->bottom = (LONG) (rectDocument->bottom * URect[uCurrentPageNumber].bottom);
    rectDocument->left   = (LONG) (rectDocument->left   * URect[uCurrentPageNumber].left);
    rectDocument->right  = (LONG) (rectDocument->right  * URect[uCurrentPageNumber].right);

    // If the page border has to drawn, return the corresponding coordinates in rectBorder.

    if (dwNupBorderFlags == BORDER_PRINT) {
        rectBorder->top    = rectDocument->top/xResolution;
        rectBorder->bottom = rectDocument->bottom/xResolution - 1;
        rectBorder->left   = rectDocument->left/yResolution;
        rectBorder->right  = rectDocument->right/yResolution - 1;
    }

    if (*pbRotate) {
        ltemp = lXFrame; lXFrame = lYFrame; lYFrame = ltemp;
    }

    // Get the new size of the rectangle to keep the X/Y ratio constant.
    if ( ((LONG) (lYFrame*((lXPhyPage*1.0)/lYPhyPage))) >= lXFrame) {
         ldX = 0;
         ldY = lYFrame - ((LONG) (lXFrame*((lYPhyPage*1.0)/lXPhyPage)));
    } else {
         ldY = 0;
         ldX = lXFrame - ((LONG) (lYFrame*((lXPhyPage*1.0)/lYPhyPage)));
    }

    // Adjust the position of the rectangle.

    if (*pbRotate) {
        if (ldX) {
            rectDocument->bottom -= (LONG) (ldX / 2.0);
            rectDocument->top    += (LONG) (ldX / 2.0);
        } else {
           rectDocument->right   -= (LONG) (ldY / 2.0);
           rectDocument->left    += (LONG) (ldY / 2.0);
        }
    } else {
        if (ldX) {
           rectDocument->left    += (LONG) (ldX / 2.0);
           rectDocument->right   -= (LONG) (ldX / 2.0);
        } else {
           rectDocument->top     += (LONG) (ldY / 2.0);
           rectDocument->bottom  -= (LONG) (ldY / 2.0);
        }
    }

    // Adjust to get the Printable Area on the rectangle

    lXOffset = GetDeviceCaps(hPrinterDC, PHYSICALOFFSETX) * yResolution;
    lYOffset = GetDeviceCaps(hPrinterDC, PHYSICALOFFSETY) * xResolution;

    dXleft = ( lXOffset * 1.0) / lXPhyPage;
    dYtop  = ( lYOffset * 1.0) / lYPhyPage;
    dXright =  ((lXPhyPage - (lXOffset + lXPrintPage)) * 1.0) / lXPhyPage;
    dYbottom = ((lYPhyPage - (lYOffset + lYPrintPage)) * 1.0) / lYPhyPage;

    lXNewPhyPage = rectDocument->right  - rectDocument->left;
    lYNewPhyPage = rectDocument->bottom - rectDocument->top;

    if (*pbRotate) {

       ltemp = lXNewPhyPage; lXNewPhyPage = lYNewPhyPage; lYNewPhyPage = ltemp;

       rectDocument->left   += (LONG) (dYtop    * lYNewPhyPage);
       rectDocument->right  -= (LONG) (dYbottom * lYNewPhyPage);
       rectDocument->top    += (LONG) (dXright  * lXNewPhyPage);
       rectDocument->bottom -= (LONG) (dXleft   * lXNewPhyPage);

    } else {

       rectDocument->left   += (LONG) (dXleft   * lXNewPhyPage);
       rectDocument->right  -= (LONG) (dXright  * lXNewPhyPage);
       rectDocument->top    += (LONG) (dYtop    * lYNewPhyPage);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -