home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / inole / xform.cpp < prev   
C/C++ Source or Header  |  1995-05-03  |  12KB  |  383 lines

  1. /*
  2.  * XFORM.CPP
  3.  *
  4.  * Utility functions for coordinate conversion taken from the
  5.  * original OLE UI Library.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #include "inoledll.h"
  16.  
  17.  
  18. #define HIMETRIC_PER_INCH   2540    //Number HIMETRIC units per inch
  19. #define PTS_PER_INCH        72      //Number points (font size) per inch
  20.  
  21. #define MAP_PIX_TO_LOGHIM(x,ppli)   MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
  22. #define MAP_LOGHIM_TO_PIX(x,ppli)   MulDiv((ppli), (x), HIMETRIC_PER_INCH)
  23.  
  24.  
  25.  
  26. /*
  27.  * XformWidthInPixelsToHimetric
  28.  * XformWidthInHimetricToPixels
  29.  * XformHeightInPixelsToHimetric
  30.  * XformHeightInHimetricToPixels
  31.  *
  32.  * Functions to convert an int between a device coordinate system and
  33.  * logical HiMetric units.
  34.  *
  35.  * Parameters:
  36.  *  hDC             HDC providing reference to the pixel mapping.  If
  37.  *                  NULL, a screen DC is used.
  38.  *  (others)        Values to convert
  39.  *
  40.  * NOTE:
  41.  *  When displaying on the screen, Window apps display everything enlarged
  42.  *  from its actual size so that it is easier to read. For example, if an
  43.  *  app wants to display a 1in. horizontal line, that when printed is
  44.  *  actually a 1in. line on the printed page, then it will display the line
  45.  *  on the screen physically larger than 1in. This is described as a line
  46.  *  that is "logically" 1in. along the display width. Windows maintains as
  47.  *  part of the device-specific information about a given display device:
  48.  *      LOGPIXELSX -- no. of pixels per logical in along the display width
  49.  *      LOGPIXELSY -- no. of pixels per logical in along the display height
  50.  *
  51.  *  The following formula converts a distance in pixels into its equivalent
  52.  *  logical HIMETRIC units:
  53.  *
  54.  *      DistInHiMetric = (HIMETRIC_PER_INCH * DistInPix)
  55.  *                       -------------------------------
  56.  *                           PIXELS_PER_LOGICAL_IN
  57.  *
  58.  */
  59.  
  60. STDAPI_(int) XformWidthInPixelsToHimetric(HDC hDC, int iWidthInPix)
  61.     {
  62.     int     iXppli;     //Pixels per logical inch along width
  63.     int     iWidthInHiMetric;
  64.     BOOL    fSystemDC=FALSE;
  65.  
  66.     if (NULL==hDC)
  67.         {
  68.         hDC=GetDC(NULL);
  69.         fSystemDC=TRUE;
  70.         }
  71.  
  72.     iXppli=GetDeviceCaps (hDC, LOGPIXELSX);
  73.  
  74.     //We got pixel units, convert them to logical HIMETRIC along the display
  75.     iWidthInHiMetric=MAP_PIX_TO_LOGHIM(iWidthInPix, iXppli);
  76.  
  77.     if (fSystemDC)
  78.         ReleaseDC(NULL, hDC);
  79.  
  80.     return iWidthInHiMetric;
  81.     }
  82.  
  83.  
  84. STDAPI_(int) XformWidthInHimetricToPixels(HDC hDC, int iWidthInHiMetric)
  85.     {
  86.     int     iXppli;     //Pixels per logical inch along width
  87.     int     iWidthInPix;
  88.     BOOL    fSystemDC=FALSE;
  89.  
  90.     if (NULL==hDC)
  91.         {
  92.         hDC=GetDC(NULL);
  93.         fSystemDC=TRUE;
  94.         }
  95.  
  96.     iXppli=GetDeviceCaps (hDC, LOGPIXELSX);
  97.  
  98.     //We got logical HIMETRIC along the display, convert them to pixel units
  99.     iWidthInPix=MAP_LOGHIM_TO_PIX(iWidthInHiMetric, iXppli);
  100.  
  101.     if (fSystemDC)
  102.         ReleaseDC(NULL, hDC);
  103.  
  104.     return iWidthInPix;
  105.     }
  106.  
  107.  
  108. STDAPI_(int) XformHeightInPixelsToHimetric(HDC hDC, int iHeightInPix)
  109.     {
  110.     int     iYppli;     //Pixels per logical inch along height
  111.     int     iHeightInHiMetric;
  112.     BOOL    fSystemDC=FALSE;
  113.  
  114.     if (NULL==hDC)
  115.         {
  116.         hDC=GetDC(NULL);
  117.         fSystemDC=TRUE;
  118.         }
  119.  
  120.     iYppli=GetDeviceCaps (hDC, LOGPIXELSY);
  121.  
  122.     //We got pixel units, convert them to logical HIMETRIC along the display
  123.     iHeightInHiMetric=MAP_PIX_TO_LOGHIM(iHeightInPix, iYppli);
  124.  
  125.     if (fSystemDC)
  126.         ReleaseDC(NULL, hDC);
  127.  
  128.     return iHeightInHiMetric;
  129.     }
  130.  
  131.  
  132. STDAPI_(int) XformHeightInHimetricToPixels(HDC hDC, int iHeightInHiMetric)
  133.     {
  134.     int     iYppli;     //Pixels per logical inch along height
  135.     int     iHeightInPix;
  136.     BOOL    fSystemDC=FALSE;
  137.  
  138.     if (NULL==hDC)
  139.         {
  140.         hDC=GetDC(NULL);
  141.         fSystemDC=TRUE;
  142.         }
  143.  
  144.     iYppli=GetDeviceCaps (hDC, LOGPIXELSY);
  145.  
  146.     //We got logical HIMETRIC along the display, convert them to pixel units
  147.     iHeightInPix=MAP_LOGHIM_TO_PIX(iHeightInHiMetric, iYppli);
  148.  
  149.     if (fSystemDC)
  150.         ReleaseDC(NULL, hDC);
  151.  
  152.     return iHeightInPix;
  153.     }
  154.  
  155.  
  156.  
  157. /*
  158.  * XformRectInPixelsToHimetric
  159.  * XformRectInHimetricToPixels
  160.  *
  161.  * Purpose:
  162.  *  Convert a rectangle between pixels of a given hDC and HIMETRIC units
  163.  *  as manipulated in OLE.  If the hDC is NULL, then a screen DC is used
  164.  *  and assumes the MM_TEXT mapping mode.
  165.  *
  166.  * Parameters:
  167.  *  hDC             HDC providing reference to the pixel mapping.  If
  168.  *                  NULL, a screen DC is used.
  169.  *  prcPix          LPRECT containng the rectangles to convert.
  170.  *  prcHiMetric
  171.  *
  172.  * Return Value:
  173.  *  None
  174.  *
  175.  * NOTE:
  176.  *  When displaying on the screen, Window apps display everything enlarged
  177.  *  from its actual size so that it is easier to read. For example, if an
  178.  *  app wants to display a 1in. horizontal line, that when printed is
  179.  *  actually a 1in. line on the printed page, then it will display the line
  180.  *  on the screen physically larger than 1in. This is described as a line
  181.  *  that is "logically" 1in. along the display width. Windows maintains as
  182.  *  part of the device-specific information about a given display device:
  183.  *      LOGPIXELSX -- no. of pixels per logical in along the display width
  184.  *      LOGPIXELSY -- no. of pixels per logical in along the display height
  185.  *
  186.  *  The following formula converts a distance in pixels into its equivalent
  187.  *  logical HIMETRIC units:
  188.  *
  189.  *      DistInHiMetric=(HIMETRIC_PER_INCH * DistInPix)
  190.  *                      -------------------------------
  191.  *                            PIXELS_PER_LOGICAL_IN
  192.  *
  193.  * Rect in Pixels (MM_TEXT):
  194.  *
  195.  *              0---------- X
  196.  *              |
  197.  *              |       1) ------------------ ( 2   P1=(rc.left, rc.top)
  198.  *              |       |                     |     P2=(rc.right, rc.top)
  199.  *              |       |                     |     P3=(rc.left, rc.bottom)
  200.  *              |       |                     |     P4=(rc.right, rc.bottom)
  201.  *                      |                     |
  202.  *              Y       |                     |
  203.  *                      3) ------------------ ( 4
  204.  *
  205.  *              NOTE:   Origin  =(P1x, P1y)
  206.  *                      X extent=P4x - P1x
  207.  *                      Y extent=P4y - P1y
  208.  *
  209.  *
  210.  * Rect in Himetric (MM_HIMETRIC):
  211.  *
  212.  *
  213.  *                      1) ------------------ ( 2   P1=(rc.left, rc.top)
  214.  *              Y       |                     |     P2=(rc.right, rc.top)
  215.  *                      |                     |     P3=(rc.left, rc.bottom)
  216.  *              |       |                     |     P4=(rc.right, rc.bottom)
  217.  *              |       |                     |
  218.  *              |       |                     |
  219.  *              |       3) ------------------ ( 4
  220.  *              |
  221.  *              0---------- X
  222.  *
  223.  *              NOTE:   Origin  =(P3x, P3y)
  224.  *                      X extent=P2x - P3x
  225.  *                      Y extent=P2y - P3y
  226.  *
  227.  *
  228.  */
  229.  
  230. STDAPI_(void) XformRectInPixelsToHimetric(HDC hDC, LPRECT prcPix
  231.     , LPRECT prcHiMetric)
  232.     {
  233.     int     iXppli;     //Pixels per logical inch along width
  234.     int     iYppli;     //Pixels per logical inch along height
  235.     int     iXextInPix=(prcPix->right-prcPix->left);
  236.     int     iYextInPix=(prcPix->bottom-prcPix->top);
  237.     BOOL    fSystemDC=FALSE;
  238.  
  239.     if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0)
  240.         {
  241.         hDC=GetDC(NULL);
  242.         fSystemDC=TRUE;
  243.         }
  244.  
  245.     iXppli=GetDeviceCaps (hDC, LOGPIXELSX);
  246.     iYppli=GetDeviceCaps (hDC, LOGPIXELSY);
  247.  
  248.     //We got pixel units, convert them to logical HIMETRIC along the display
  249.     prcHiMetric->right=MAP_PIX_TO_LOGHIM(iXextInPix, iXppli);
  250.     prcHiMetric->top  =MAP_PIX_TO_LOGHIM(iYextInPix, iYppli);
  251.  
  252.     prcHiMetric->left   =0;
  253.     prcHiMetric->bottom =0;
  254.  
  255.     if (fSystemDC)
  256.         ReleaseDC(NULL, hDC);
  257.  
  258.     return;
  259.     }
  260.  
  261.  
  262.  
  263. STDAPI_(void) XformRectInHimetricToPixels(HDC hDC, LPRECT prcHiMetric
  264.     , LPRECT prcPix)
  265.     {
  266.     int     iXppli;     //Pixels per logical inch along width
  267.     int     iYppli;     //Pixels per logical inch along height
  268.     int     iXextInHiMetric=(prcHiMetric->right-prcHiMetric->left);
  269.     int     iYextInHiMetric=(prcHiMetric->bottom-prcHiMetric->top);
  270.     BOOL    fSystemDC=FALSE;
  271.  
  272.     if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0)
  273.         {
  274.         hDC=GetDC(NULL);
  275.         fSystemDC=TRUE;
  276.         }
  277.  
  278.     iXppli=GetDeviceCaps (hDC, LOGPIXELSX);
  279.     iYppli=GetDeviceCaps (hDC, LOGPIXELSY);
  280.  
  281.     //We got pixel units, convert them to logical HIMETRIC along the display
  282.     prcPix->right=MAP_LOGHIM_TO_PIX(iXextInHiMetric, iXppli);
  283.     prcPix->top  =MAP_LOGHIM_TO_PIX(iYextInHiMetric, iYppli);
  284.  
  285.     prcPix->left =0;
  286.     prcPix->bottom= 0;
  287.  
  288.     if (fSystemDC)
  289.         ReleaseDC(NULL, hDC);
  290.  
  291.     return;
  292.     }
  293.  
  294.  
  295.  
  296.  
  297. /*
  298.  * XformSizeInPixelsToHimetric
  299.  * XformSizeInHimetricToPixels
  300.  *
  301.  * Functions to convert a SIZEL structure (Size functions) or
  302.  * an int (Width functions) between a device coordinate system and
  303.  * logical HiMetric units.
  304.  *
  305.  * Parameters:
  306.  *  hDC             HDC providing reference to the pixel mapping.  If
  307.  *                  NULL, a screen DC is used.
  308.  *  pSizeInPix      LPSIZEL containing the size to convert.
  309.  *  pSizeInHiMetric
  310.  *
  311.  * NOTE:
  312.  *  When displaying on the screen, Window apps display everything enlarged
  313.  *  from its actual size so that it is easier to read. For example, if an
  314.  *  app wants to display a 1in. horizontal line, that when printed is
  315.  *  actually a 1in. line on the printed page, then it will display the line
  316.  *  on the screen physically larger than 1in. This is described as a line
  317.  *  that is "logically" 1in. along the display width. Windows maintains as
  318.  *  part of the device-specific information about a given display device:
  319.  *      LOGPIXELSX -- no. of pixels per logical in along the display width
  320.  *      LOGPIXELSY -- no. of pixels per logical in along the display height
  321.  *
  322.  *  The following formula converts a distance in pixels into its equivalent
  323.  *  logical HIMETRIC units:
  324.  *
  325.  *      DistInHiMetric=(HIMETRIC_PER_INCH * DistInPix)
  326.  *                       -------------------------------
  327.  *                           PIXELS_PER_LOGICAL_IN
  328.  *
  329.  */
  330.  
  331. STDAPI_(void) XformSizeInPixelsToHimetric(HDC hDC, LPSIZEL pSizeInPix
  332.     , LPSIZEL pSizeInHiMetric)
  333.     {
  334.     int     iXppli;     //Pixels per logical inch along width
  335.     int     iYppli;     //Pixels per logical inch along height
  336.     BOOL    fSystemDC=FALSE;
  337.  
  338.     if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0)
  339.         {
  340.         hDC=GetDC(NULL);
  341.         fSystemDC=TRUE;
  342.         }
  343.  
  344.     iXppli=GetDeviceCaps (hDC, LOGPIXELSX);
  345.     iYppli=GetDeviceCaps (hDC, LOGPIXELSY);
  346.  
  347.     //We got pixel units, convert them to logical HIMETRIC along the display
  348.     pSizeInHiMetric->cx=(long)MAP_PIX_TO_LOGHIM((int)pSizeInPix->cx, iXppli);
  349.     pSizeInHiMetric->cy=(long)MAP_PIX_TO_LOGHIM((int)pSizeInPix->cy, iYppli);
  350.  
  351.     if (fSystemDC)
  352.         ReleaseDC(NULL, hDC);
  353.  
  354.     return;
  355.     }
  356.  
  357.  
  358. STDAPI_(void) XformSizeInHimetricToPixels(HDC hDC, LPSIZEL pSizeInHiMetric
  359.     , LPSIZEL pSizeInPix)
  360.     {
  361.     int     iXppli;     //Pixels per logical inch along width
  362.     int     iYppli;     //Pixels per logical inch along height
  363.     BOOL    fSystemDC=FALSE;
  364.  
  365.     if (NULL==hDC || GetDeviceCaps(hDC, LOGPIXELSX) == 0)
  366.         {
  367.         hDC=GetDC(NULL);
  368.         fSystemDC=TRUE;
  369.         }
  370.  
  371.     iXppli=GetDeviceCaps (hDC, LOGPIXELSX);
  372.     iYppli=GetDeviceCaps (hDC, LOGPIXELSY);
  373.  
  374.     //We got logical HIMETRIC along the display, convert them to pixel units
  375.     pSizeInPix->cx=(long)MAP_LOGHIM_TO_PIX((int)pSizeInHiMetric->cx, iXppli);
  376.     pSizeInPix->cy=(long)MAP_LOGHIM_TO_PIX((int)pSizeInHiMetric->cy, iYppli);
  377.  
  378.     if (fSystemDC)
  379.         ReleaseDC(NULL, hDC);
  380.  
  381.     return;
  382.     }
  383.