home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / emf.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  7.0 KB  |  248 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : emf.cpp                                                             //
  10. //  Description: Generic enhanced metafile handling                                  //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <tchar.h>
  19. #include <assert.h>
  20. #include <math.h>
  21. #include <commdlg.h>
  22. #include <stdio.h>
  23.  
  24. #include "emf.h"
  25. #include "filedialog.h"
  26.  
  27.  
  28. // map a rectangle in logical coordinate to 0.01 mm units
  29. void Map10um(HDC hDC, RECT & rect)
  30. {
  31.     int widthmm    = GetDeviceCaps(hDC, HORZSIZE);
  32.     int heightmm   = GetDeviceCaps(hDC, VERTSIZE);
  33.     int widthpixel = GetDeviceCaps(hDC, HORZRES);
  34.     int heightpixel= GetDeviceCaps(hDC, VERTRES);
  35.  
  36.     LPtoDP(hDC, (POINT *) & rect, 2);
  37.  
  38.     rect.left   = ( rect.left   * widthmm  * 100 + widthpixel/2)  /  widthpixel;
  39.     rect.right  = ( rect.right  * widthmm  * 100 + widthpixel/2)  /  widthpixel;
  40.     rect.top    = ( rect.top    * heightmm * 100 + heightpixel/2) / heightpixel;
  41.     rect.bottom = ( rect.bottom * heightmm * 100 + heightpixel/2) / heightpixel;
  42. }
  43.  
  44.  
  45. // load an EMF attached as a resource, use RCDATA as type
  46. HENHMETAFILE LoadEMF(HMODULE hModule, LPCTSTR pName)
  47. {
  48.     HRSRC hRsc       = FindResource(hModule, pName, RT_RCDATA);
  49.         
  50.     if ( hRsc==NULL )
  51.         return NULL;
  52.  
  53.     HGLOBAL hResData = LoadResource(hModule, hRsc);
  54.     LPVOID  pEmf     = LockResource(hResData);
  55.  
  56.     return SetEnhMetaFileBits(SizeofResource(hModule, hRsc), (const BYTE *) pEmf);
  57. }
  58.  
  59.  
  60. // query for EMF dimension, convert to logical coordinate
  61. void GetEMFDimension(HDC hDC, HENHMETAFILE hEmf, int & width, int & height)
  62. {
  63.     ENHMETAHEADER emfh[5]; // big enough for description
  64.     GetEnhMetaFileHeader(hEmf, sizeof(emfh), emfh);
  65.  
  66.     // picture size in 0.01 mm
  67.     width  = emfh[0].rclFrame.right  - emfh[0].rclFrame.left;
  68.     height = emfh[0].rclFrame.bottom - emfh[0].rclFrame.top;
  69.  
  70.     // convert to pixels for current device
  71.     int  t = GetDeviceCaps(hDC, HORZSIZE) * 100; 
  72.     width  = ( width  * GetDeviceCaps(hDC, HORZRES) + t/2 ) / t;
  73.  
  74.          t = GetDeviceCaps(hDC, VERTSIZE) * 100;
  75.     height = ( height * GetDeviceCaps(hDC, VERTRES) + t/2 ) / t;
  76.  
  77.     RECT rect = { 0, 0, width, height };
  78.  
  79.     // convert to logical coordinate space
  80.     DPtoLP(hDC, (POINT *) & rect, 2);
  81.  
  82.     width  = abs(rect.right - rect.left);
  83.     height = abs(rect.bottom - rect.top);
  84. }
  85.  
  86.  
  87. // displaying EMF at a given ratio
  88. BOOL DisplayEMF(HDC hDC, HENHMETAFILE hEmf, int x, int y, int scalex, int scaley, KEnumEMF * enumerator, bool showxform)
  89. {
  90.     int width, height;
  91.     GetEMFDimension(hDC, hEmf, width, height);
  92.  
  93.     RECT rect = { x, y, 
  94.         x + (width  * scalex + 50)/100, 
  95.         y + (height * scaley + 50)/100 };
  96.  
  97.     BOOL rslt;
  98.  
  99.     if ( enumerator )
  100.         rslt = enumerator->EnumEMF(hDC, hEmf, & rect);
  101.     else
  102.         rslt = PlayEnhMetaFile(hDC, hEmf, & rect);
  103.  
  104.     if ( showxform )
  105.     {
  106.         XFORM xform;
  107.  
  108.         if ( GetPlayTransformation(hEmf, & rect, xform) )
  109.         {
  110.             TCHAR mess[128];
  111.  
  112.             _stprintf(mess, _T("x' = x * %8.5f + y * %8.5f + %8.5f"), xform.eM11, xform.eM21, xform.eDx);
  113.             TextOut(hDC, x, rect.bottom + 10, mess, _tcslen(mess));
  114.  
  115.             _stprintf(mess, _T("y' = x * %8.5f + y * %8.5f + %8.5f"), xform.eM12, xform.eM22, xform.eDy);
  116.             TextOut(hDC, x, rect.bottom + 40, mess, _tcslen(mess));
  117.         }
  118.     }
  119.  
  120.     return rslt;
  121. }
  122.  
  123.  
  124. HDC QuerySaveEMFFile(const TCHAR * description, const RECT * rcFrame, TCHAR szFileName[])
  125. {
  126.     KFileDialog fd;
  127.  
  128.     if ( fd.GetSaveFileName(NULL, _T("emf"), _T("Enhanced Metafiles")) )
  129.     {
  130.         if ( szFileName )
  131.             _tcscpy(szFileName, fd.m_TitleName);
  132.  
  133.         return CreateEnhMetaFile(NULL, fd.m_TitleName, rcFrame, description);
  134.     }
  135.     else
  136.         return NULL;
  137. }
  138.  
  139.  
  140. HENHMETAFILE QueryOpenEMFFile(TCHAR szFileName[])
  141. {
  142.     KFileDialog fd;
  143.  
  144.     if ( fd.GetOpenFileName(NULL, _T("emf|spl"), _T("Enhanced Metafiles|Win NT/2000 EMF Spool Files")) )
  145.     {
  146.         if ( szFileName )
  147.             _tcscpy(szFileName, fd.m_TitleName);
  148.         
  149.         return  GetEnhMetaFile(fd.m_TitleName);
  150.     }
  151.     else
  152.         return NULL;
  153. }
  154.  
  155.  
  156. HENHMETAFILE PasteFromClipboard(HWND hWnd)
  157. {
  158.     HENHMETAFILE hEmf = NULL;
  159.  
  160.     if ( OpenClipboard(hWnd) )
  161.     {
  162.         hEmf = (HENHMETAFILE) GetClipboardData(CF_ENHMETAFILE);
  163.  
  164.         if ( hEmf )
  165.             hEmf = CopyEnhMetaFile(hEmf, NULL);
  166.  
  167.         CloseClipboard();
  168.     }
  169.  
  170.     return hEmf;
  171. }
  172.  
  173.  
  174. void CopyToClipboard(HWND hWnd, HENHMETAFILE hEmf)
  175. {
  176.     if ( OpenClipboard(hWnd) )
  177.     {
  178.         EmptyClipboard();
  179.         SetClipboardData(CF_ENHMETAFILE, hEmf);
  180.         CloseClipboard();
  181.     }
  182. }
  183.  
  184.  
  185.  
  186. HPALETTE GetEMFPalette(HENHMETAFILE hEmf, HDC hDC)
  187. {
  188.     // query number of entries
  189.     int no = GetEnhMetaFilePaletteEntries(hEmf, 0, NULL);
  190.  
  191.     if ( no<=0 )
  192.         return NULL;
  193.  
  194.     // allocation
  195.     LOGPALETTE * pLogPalette = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) + (no-1) * sizeof(PALETTEENTRY)];
  196.  
  197.     pLogPalette->palVersion    = 0x300;
  198.     pLogPalette->palNumEntries = no;
  199.  
  200.     // get real data
  201.     GetEnhMetaFilePaletteEntries(hEmf, no, pLogPalette->palPalEntry);
  202.  
  203.     HPALETTE hPal = CreatePalette(pLogPalette);
  204.  
  205.     delete [] (BYTE *) pLogPalette;
  206.  
  207.     return hPal;
  208. }
  209.  
  210.  
  211. // Transformation to map recording device's device coordinate space to destination device's logical coordinate space
  212. BOOL GetPlayTransformation(HENHMETAFILE hEmf, const RECT * rcPic, XFORM & xformPlay)
  213. {
  214.     ENHMETAHEADER emfh; 
  215.     
  216.     if ( GetEnhMetaFileHeader(hEmf, sizeof(emfh), & emfh)<=0 )
  217.         return FALSE;
  218.  
  219.     try
  220.     {
  221.         // frame rectangle size in 0.01 mm -> 1 mm -> percentage -> device pixels
  222.         double sx0 = emfh.rclFrame.left   / 100.0 / emfh.szlMillimeters.cx * emfh.szlDevice.cx;
  223.         double sy0 = emfh.rclFrame.top    / 100.0 / emfh.szlMillimeters.cy * emfh.szlDevice.cy;
  224.         double sx1 = emfh.rclFrame.right  / 100.0 / emfh.szlMillimeters.cx * emfh.szlDevice.cx;
  225.         double sy1 = emfh.rclFrame.bottom / 100.0 / emfh.szlMillimeters.cy * emfh.szlDevice.cy;
  226.  
  227.         // source to destination ratio
  228.         double rx  = (rcPic->right  - rcPic->left) / ( sx1 - sx0 );
  229.         double ry  = (rcPic->bottom - rcPic->top)  / ( sy1 - sy0 );
  230.  
  231.         // x' = x * eM11 + y * eM21 + eDx
  232.         // y' = x * eM12 + y * eM22 + eDy
  233.         xformPlay.eM11 = (float) rx;
  234.         xformPlay.eM21 = (float) 0;
  235.         xformPlay.eDx  = (float) (- sx0 * rx + rcPic->left);
  236.  
  237.         xformPlay.eM12 = (float) 0;
  238.         xformPlay.eM22 = (float) ry;
  239.         xformPlay.eDy  = (float) (- sy0 * ry + rcPic->top);
  240.     }
  241.     catch (...)
  242.     {
  243.         return FALSE;
  244.     }
  245.  
  246.     return TRUE;
  247. }
  248.