home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / metafile.cpp < prev    next >
C/C++ Source or Header  |  2000-07-15  |  10KB  |  419 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        metafile.cpp
  3. // Purpose:     wxMetaFile, wxMetaFileDC etc. These classes are optional.
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/10/99
  7. // RCS-ID:      $Id: METAFILE.CPP,v 1.5 2000/07/15 19:50:39 cvsuser Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // For compilers that support precompilation, includes "wx.h".
  13. #include "wx/wxprec.h"
  14.  
  15. #ifndef WX_PRECOMP
  16. #include "wx/setup.h"
  17. #endif
  18.  
  19. #if wxUSE_METAFILE
  20.  
  21. #ifndef WX_PRECOMP
  22. #include "wx/utils.h"
  23. #include "wx/app.h"
  24. #endif
  25.  
  26. #include "wx/metafile.h"
  27. #include "wx/clipbrd.h"
  28. #include "wx/os2/private.h"
  29.  
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. extern bool wxClipboardIsOpen;
  34.  
  35. IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject)
  36. IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
  37.  
  38. /*
  39.  * Metafiles
  40.  * Currently, the only purpose for making a metafile is to put
  41.  * it on the clipboard.
  42.  */
  43.  
  44. wxMetafileRefData::wxMetafileRefData(void)
  45. {
  46.     m_metafile = 0;
  47.     m_windowsMappingMode = wxMM_ANISOTROPIC;
  48. }
  49.  
  50. wxMetafileRefData::~wxMetafileRefData(void)
  51. {
  52.     if (m_metafile)
  53.     {
  54. // TODO: DeleteMetaFile((HMETAFILE) m_metafile);
  55.          m_metafile = 0;
  56.     }
  57. }
  58.  
  59. wxMetafile::wxMetafile(const wxString& file)
  60. {
  61.     m_refData = new wxMetafileRefData;
  62.  
  63.     M_METAFILEDATA->m_windowsMappingMode = wxMM_ANISOTROPIC;
  64.     M_METAFILEDATA->m_metafile = 0;
  65.     if (!file.IsNull() && (file.Cmp(wxT("")) == 0))
  66.         M_METAFILEDATA->m_metafile = (WXHANDLE)0; // TODO: GetMetaFile(file);
  67. }
  68.  
  69. wxMetafile::~wxMetafile(void)
  70. {
  71. }
  72.  
  73. bool wxMetafile::SetClipboard(int width, int height)
  74. {
  75.     if (!m_refData)
  76.         return FALSE;
  77.  
  78.     bool alreadyOpen=wxClipboardOpen();
  79.     if (!alreadyOpen)
  80.     {
  81.         wxOpenClipboard();
  82.         if (!wxEmptyClipboard()) return FALSE;
  83.     }
  84.     bool success = wxSetClipboardData(wxDF_METAFILE, this, width,height);
  85.     if (!alreadyOpen) wxCloseClipboard();
  86.     return (bool) success;
  87. }
  88.  
  89. bool wxMetafile::Play(wxDC *dc)
  90. {
  91.     if (!m_refData)
  92.         return FALSE;
  93.  
  94.     dc->BeginDrawing();
  95.  
  96.  //   if (dc->GetHDC() && M_METAFILEDATA->m_metafile)
  97.  //       PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile);
  98.  
  99.     dc->EndDrawing();
  100.  
  101.     return TRUE;
  102. }
  103.  
  104. void wxMetafile::SetHMETAFILE(WXHANDLE mf)
  105. {
  106.     if (m_refData)
  107.         m_refData = new wxMetafileRefData;
  108.  
  109.     M_METAFILEDATA->m_metafile = mf;
  110. }
  111.  
  112. void wxMetafile::SetWindowsMappingMode(int mm)
  113. {
  114.     if (m_refData)
  115.         m_refData = new wxMetafileRefData;
  116.  
  117.     M_METAFILEDATA->m_windowsMappingMode = mm;
  118. }
  119.  
  120. /*
  121.  * Metafile device context
  122.  *
  123.  */
  124.  
  125. // Original constructor that does not takes origin and extent. If you use this,
  126. // *DO* give origin/extent arguments to wxMakeMetafilePlaceable.
  127. wxMetafileDC::wxMetafileDC(const wxString& file)
  128. {
  129.   m_metaFile = NULL;
  130.   m_minX = 10000;
  131.   m_minY = 10000;
  132.   m_maxX = -10000;
  133.   m_maxY = -10000;
  134. //  m_title = NULL;
  135.  
  136.   if (!file.IsNull() && wxFileExists(file))
  137.     wxRemoveFile(file);
  138.  
  139.   // TODO
  140. /*
  141.   if (!file.IsNull() && (file != wxT("")))
  142.     m_hDC = (WXHDC) CreateMetaFile(file);
  143.   else
  144.     m_hDC = (WXHDC) CreateMetaFile(NULL);
  145. */
  146.  
  147.   m_ok = (m_hDC != (WXHDC) 0) ;
  148.  
  149.   // Actual Windows mapping mode, for future reference.
  150.   m_windowsMappingMode = wxMM_TEXT;
  151.  
  152.   SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct)
  153. }
  154.  
  155. // New constructor that takes origin and extent. If you use this, don't
  156. // give origin/extent arguments to wxMakeMetafilePlaceable.
  157. wxMetafileDC::wxMetafileDC(const wxString& file, int xext, int yext, int xorg, int yorg)
  158. {
  159.   m_minX = 10000;
  160.   m_minY = 10000;
  161.   m_maxX = -10000;
  162.   m_maxY = -10000;
  163.   if (file != wxT("") && wxFileExists(file)) wxRemoveFile(file);
  164. //  m_hDC = (WXHDC) CreateMetaFile(file);
  165.  
  166.   m_ok = TRUE;
  167.  
  168. //  ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL);
  169. //  ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL);
  170.  
  171.   // Actual Windows mapping mode, for future reference.
  172.   m_windowsMappingMode = wxMM_ANISOTROPIC;
  173.  
  174.   SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct)
  175. }
  176.  
  177. wxMetafileDC::~wxMetafileDC(void)
  178. {
  179.   m_hDC = 0;
  180. }
  181.  
  182. void wxMetafileDC::GetTextExtent(const wxString& string, long *x, long *y,
  183.                                  long *descent, long *externalLeading, wxFont *theFont, bool use16bit) const
  184. {
  185.   wxFont *fontToUse = theFont;
  186.   if (!fontToUse)
  187.     fontToUse = (wxFont*) &m_font;
  188.  
  189.   // TODO:
  190. /*
  191.   HDC dc = GetDC(NULL);
  192.  
  193.   SIZE sizeRect;
  194.   TEXTMETRIC tm;
  195.   GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect);
  196.   GetTextMetrics(dc, &tm);
  197.  
  198.   ReleaseDC(NULL, dc);
  199.  
  200.   if ( x )
  201.       *x = sizeRect.cx;
  202.   if ( y )
  203.     *y = sizeRect.cy;
  204.   if ( descent )
  205.       *descent = tm.tmDescent;
  206.   if ( externalLeading )
  207.       *externalLeading = tm.tmExternalLeading;
  208. */
  209. }
  210.  
  211. wxMetafile *wxMetafileDC::Close(void)
  212. {
  213.   SelectOldObjects(m_hDC);
  214.   HANDLE mf = 0; // TODO: CloseMetaFile((HDC) m_hDC);
  215.   m_hDC = 0;
  216.   if (mf)
  217.   {
  218.     wxMetafile *wx_mf = new wxMetafile;
  219.     wx_mf->SetHMETAFILE((WXHANDLE) mf);
  220.     wx_mf->SetWindowsMappingMode(m_windowsMappingMode);
  221.     return wx_mf;
  222.   }
  223.   return NULL;
  224. }
  225.  
  226. void wxMetafileDC::SetMapMode(int mode)
  227. {
  228.   m_mappingMode = mode;
  229.  
  230. //  int pixel_width = 0;
  231. //  int pixel_height = 0;
  232. //  int mm_width = 0;
  233. //  int mm_height = 0;
  234.  
  235.   float mm2pixelsX = 10.0;
  236.   float mm2pixelsY = 10.0;
  237.  
  238.   switch (mode)
  239.   {
  240.     case wxMM_TWIPS:
  241.     {
  242.       m_logicalScaleX = (float)(twips2mm * mm2pixelsX);
  243.       m_logicalScaleY = (float)(twips2mm * mm2pixelsY);
  244.       break;
  245.     }
  246.     case wxMM_POINTS:
  247.     {
  248.       m_logicalScaleX = (float)(pt2mm * mm2pixelsX);
  249.       m_logicalScaleY = (float)(pt2mm * mm2pixelsY);
  250.       break;
  251.     }
  252.     case wxMM_METRIC:
  253.     {
  254.       m_logicalScaleX = mm2pixelsX;
  255.       m_logicalScaleY = mm2pixelsY;
  256.       break;
  257.     }
  258.     case wxMM_LOMETRIC:
  259.     {
  260.       m_logicalScaleX = (float)(mm2pixelsX/10.0);
  261.       m_logicalScaleY = (float)(mm2pixelsY/10.0);
  262.       break;
  263.     }
  264.     default:
  265.     case wxMM_TEXT:
  266.     {
  267.       m_logicalScaleX = 1.0;
  268.       m_logicalScaleY = 1.0;
  269.       break;
  270.     }
  271.   }
  272.   m_nWindowExtX = 100;
  273.   m_nWindowExtY = 100;
  274. }
  275.  
  276. #ifdef __WIN32__
  277. struct RECT32
  278. {
  279.   short left;
  280.   short top;
  281.   short right;
  282.   short bottom;
  283. };
  284.  
  285. struct mfPLACEABLEHEADER {
  286.     DWORD    key;
  287.     short    hmf;
  288.     RECT32    bbox;
  289.     WORD    inch;
  290.     DWORD    reserved;
  291.     WORD    checksum;
  292. };
  293. #else
  294. struct mfPLACEABLEHEADER {
  295.     DWORD    key;
  296.     HANDLE    hmf;
  297.     RECT    bbox;
  298.     WORD    inch;
  299.     DWORD    reserved;
  300.     WORD    checksum;
  301. };
  302. #endif
  303.  
  304. /*
  305.  * Pass filename of existing non-placeable metafile, and bounding box.
  306.  * Adds a placeable metafile header, sets the mapping mode to anisotropic,
  307.  * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode.
  308.  *
  309.  */
  310.  
  311. bool wxMakeMetafilePlaceable(const wxString& filename, float scale)
  312. {
  313.   return wxMakeMetafilePlaceable(filename, 0, 0, 0, 0, scale, FALSE);
  314. }
  315.  
  316. bool wxMakeMetafilePlaceable(const wxString& filename, int x1, int y1, int x2, int y2, float scale, bool useOriginAndExtent)
  317. {
  318. // TODO:  the OS/2 PM/MM way to do this
  319. /*
  320.   // I'm not sure if this is the correct way of suggesting a scale
  321.   // to the client application, but it's the only way I can find.
  322.   int unitsPerInch = (int)(576/scale);
  323.  
  324.   mfPLACEABLEHEADER header;
  325.   header.key = 0x9AC6CDD7L;
  326.   header.hmf = 0;
  327.   header.bbox.xLeft = (int)(x1);
  328.   header.bbox.yTop = (int)(y1);
  329.   header.bbox.xRight = (int)(x2);
  330.   header.bbox.yBottom = (int)(y2);
  331.   header.inch = unitsPerInch;
  332.   header.reserved = 0;
  333.  
  334.   // Calculate checksum
  335.   WORD *p;
  336.   mfPLACEABLEHEADER *pMFHead = &header;
  337.   for (p =(WORD *)pMFHead,pMFHead -> checksum = 0;
  338.     p < (WORD *)&pMFHead ->checksum; ++p)
  339.        pMFHead ->checksum ^= *p;
  340.  
  341.   FILE *fd = fopen(filename.fn_str(), "rb");
  342.   if (!fd) return FALSE;
  343.  
  344.   wxChar tempFileBuf[256];
  345.   wxGetTempFileName(wxT("mf"), tempFileBuf);
  346.   FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb");
  347.   if (!fHandle)
  348.     return FALSE;
  349.   fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle);
  350.  
  351.   // Calculate origin and extent
  352.   int originX = x1;
  353.   int originY = y1;
  354.   int extentX = x2 - x1;
  355.   int extentY = (y2 - y1);
  356.  
  357.   // Read metafile header and write
  358.   METAHEADER metaHeader;
  359.   fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd);
  360.  
  361.   if (useOriginAndExtent)
  362.     metaHeader.mtSize += 15;
  363.   else
  364.     metaHeader.mtSize += 5;
  365.  
  366.   fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle);
  367.  
  368.   // Write SetMapMode, SetWindowOrigin and SetWindowExt records
  369.   char modeBuffer[8];
  370.   char originBuffer[10];
  371.   char extentBuffer[10];
  372.   METARECORD *modeRecord = (METARECORD *)&modeBuffer;
  373.  
  374.   METARECORD *originRecord = (METARECORD *)&originBuffer;
  375.   METARECORD *extentRecord = (METARECORD *)&extentBuffer;
  376.  
  377.   modeRecord->rdSize = 4;
  378.   modeRecord->rdFunction = META_SETMAPMODE;
  379.   modeRecord->rdParm[0] = MM_ANISOTROPIC;
  380.  
  381.   originRecord->rdSize = 5;
  382.   originRecord->rdFunction = META_SETWINDOWORG;
  383.   originRecord->rdParm[0] = originY;
  384.   originRecord->rdParm[1] = originX;
  385.  
  386.   extentRecord->rdSize = 5;
  387.   extentRecord->rdFunction = META_SETWINDOWEXT;
  388.   extentRecord->rdParm[0] = extentY;
  389.   extentRecord->rdParm[1] = extentX;
  390.  
  391.   fwrite((void *)modeBuffer, sizeof(char), 8, fHandle);
  392.  
  393.   if (useOriginAndExtent)
  394.   {
  395.     fwrite((void *)originBuffer, sizeof(char), 10, fHandle);
  396.     fwrite((void *)extentBuffer, sizeof(char), 10, fHandle);
  397.   }
  398.  
  399.   int ch = -2;
  400.   while (ch != EOF)
  401.   {
  402.     ch = getc(fd);
  403.     if (ch != EOF)
  404.     {
  405.       putc(ch, fHandle);
  406.     }
  407.   }
  408.   fclose(fHandle);
  409.   fclose(fd);
  410.   wxRemoveFile(filename);
  411.   wxCopyFile(tempFileBuf, filename);
  412.   wxRemoveFile(tempFileBuf);
  413. */
  414.   return TRUE;
  415. }
  416.  
  417. #endif // wxUSE_METAFILE
  418.  
  419.