]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/metafile.cpp
020041396f7be3a0b0a64146e21c937803c2945f
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/os2/metafile.cpp 
   3 // Purpose:     wxMetaFile, wxMetaFileDC etc. These classes are optional. 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  22 #include "wx/metafile.h" 
  23 #include "wx/clipbrd.h" 
  24 #include "wx/os2/private.h" 
  29 extern bool wxClipboardIsOpen
; 
  31 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
) 
  32 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
) 
  36  * Currently, the only purpose for making a metafile is to put 
  37  * it on the clipboard. 
  40 wxMetafileRefData::wxMetafileRefData(void) 
  43     m_windowsMappingMode 
= wxMM_ANISOTROPIC
; 
  46 wxMetafileRefData::~wxMetafileRefData(void) 
  50 // TODO: DeleteMetaFile((HMETAFILE) m_metafile); 
  55 wxMetafile::wxMetafile(const wxString
& file
) 
  57     m_refData 
= new wxMetafileRefData
; 
  59     M_METAFILEDATA
->m_windowsMappingMode 
= wxMM_ANISOTROPIC
; 
  60     M_METAFILEDATA
->m_metafile 
= 0; 
  62         M_METAFILEDATA
->m_metafile 
= (WXHANDLE
)0; // TODO: GetMetaFile(file); 
  65 wxMetafile::~wxMetafile(void) 
  69 bool wxMetafile::SetClipboard(int width
, int height
) 
  79     bool alreadyOpen
=wxClipboardOpen(); 
  83         if (!wxEmptyClipboard()) return false; 
  85     bool success 
= wxSetClipboardData(wxDF_METAFILE
, this, width
,height
); 
  86     if (!alreadyOpen
) wxCloseClipboard(); 
  87     return (bool) success
; 
  91 bool wxMetafile::Play(wxDC 
*dc
) 
  96  //   if (dc->GetHDC() && M_METAFILEDATA->m_metafile) 
  97  //       PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile); 
 102 void wxMetafile::SetHMETAFILE(WXHANDLE mf
) 
 105         m_refData 
= new wxMetafileRefData
; 
 107     M_METAFILEDATA
->m_metafile 
= mf
; 
 110 void wxMetafile::SetWindowsMappingMode(int mm
) 
 113         m_refData 
= new wxMetafileRefData
; 
 115     M_METAFILEDATA
->m_windowsMappingMode 
= mm
; 
 119  * Metafile device context 
 123 // Original constructor that does not takes origin and extent. If you use this, 
 124 // *DO* give origin/extent arguments to wxMakeMetafilePlaceable. 
 125 wxMetafileDC::wxMetafileDC(const wxString
& file
) 
 134   if (!file
.IsNull() && wxFileExists(file
)) 
 140     m_hDC = (WXHDC) CreateMetaFile(file); 
 142     m_hDC = (WXHDC) CreateMetaFile(NULL); 
 145   m_ok 
= (m_hDC 
!= (WXHDC
) 0) ; 
 147   // Actual Windows mapping mode, for future reference. 
 148   m_windowsMappingMode 
= wxMM_TEXT
; 
 150   SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct) 
 153 // New constructor that takes origin and extent. If you use this, don't 
 154 // give origin/extent arguments to wxMakeMetafilePlaceable. 
 155 wxMetafileDC::wxMetafileDC( const wxString
& file
, 
 165     if (!file
.empty() && wxFileExists(file
)) 
 168 //  m_hDC = (WXHDC) CreateMetaFile(file); 
 172 //  ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL); 
 173 //  ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL); 
 175     // Actual Windows mapping mode, for future reference. 
 176     m_windowsMappingMode 
= wxMM_ANISOTROPIC
; 
 178     SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct) 
 181 wxMetafileDC::~wxMetafileDC(void) 
 186 void wxMetafileDC::GetTextExtent(const wxString
& WXUNUSED(string
), 
 189                                  long *WXUNUSED(descent
), 
 190                                  long *WXUNUSED(externalLeading
), 
 192                                  bool WXUNUSED(use16bit
) ) const 
 194     wxFont 
*fontToUse 
= theFont
; 
 196         fontToUse 
= (wxFont
*) &m_font
; 
 200     HDC dc = GetDC(NULL); 
 204     GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); 
 205     GetTextMetrics(dc, &tm); 
 214         *descent = tm.tmDescent; 
 215     if ( externalLeading ) 
 216         *externalLeading = tm.tmExternalLeading; 
 220 wxMetafile 
*wxMetafileDC::Close(void) 
 222   SelectOldObjects(m_hDC
); 
 223   HANDLE mf 
= 0; // TODO: CloseMetaFile((HDC) m_hDC); 
 227     wxMetafile 
*wx_mf 
= new wxMetafile
; 
 228     wx_mf
->SetHMETAFILE((WXHANDLE
) mf
); 
 229     wx_mf
->SetWindowsMappingMode(m_windowsMappingMode
); 
 235 void wxMetafileDC::SetMapMode(int mode
) 
 237   m_mappingMode 
= mode
; 
 239 //  int pixel_width = 0; 
 240 //  int pixel_height = 0; 
 242 //  int mm_height = 0; 
 244   float mm2pixelsX 
= 10.0; 
 245   float mm2pixelsY 
= 10.0; 
 251       m_logicalScaleX 
= (float)(twips2mm 
* mm2pixelsX
); 
 252       m_logicalScaleY 
= (float)(twips2mm 
* mm2pixelsY
); 
 257       m_logicalScaleX 
= (float)(pt2mm 
* mm2pixelsX
); 
 258       m_logicalScaleY 
= (float)(pt2mm 
* mm2pixelsY
); 
 263       m_logicalScaleX 
= mm2pixelsX
; 
 264       m_logicalScaleY 
= mm2pixelsY
; 
 269       m_logicalScaleX 
= (float)(mm2pixelsX
/10.0); 
 270       m_logicalScaleY 
= (float)(mm2pixelsY
/10.0); 
 276       m_logicalScaleX 
= 1.0; 
 277       m_logicalScaleY 
= 1.0; 
 294 struct mfPLACEABLEHEADER 
{ 
 303 struct mfPLACEABLEHEADER 
{ 
 314  * Pass filename of existing non-placeable metafile, and bounding box. 
 315  * Adds a placeable metafile header, sets the mapping mode to anisotropic, 
 316  * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode. 
 320 bool wxMakeMetafilePlaceable(const wxString
& filename
, float scale
) 
 322   return wxMakeMetafilePlaceable(filename
, 0, 0, 0, 0, scale
, FALSE
); 
 325 bool wxMakeMetafilePlaceable(const wxString
& WXUNUSED(filename
), 
 330                              float WXUNUSED(scale
), 
 331                              bool WXUNUSED(useOriginAndExtent
)) 
 333 // TODO:  the OS/2 PM/MM way to do this 
 335     // I'm not sure if this is the correct way of suggesting a scale 
 336     // to the client application, but it's the only way I can find. 
 337     int unitsPerInch = (int)(576/scale); 
 339     mfPLACEABLEHEADER header; 
 340     header.key = 0x9AC6CDD7L; 
 342     header.bbox.xLeft = (int)(x1); 
 343     header.bbox.yTop = (int)(y1); 
 344     header.bbox.xRight = (int)(x2); 
 345     header.bbox.yBottom = (int)(y2); 
 346     header.inch = unitsPerInch; 
 349     // Calculate checksum 
 351     mfPLACEABLEHEADER *pMFHead = &header; 
 352     for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; p < (WORD *)&pMFHead ->checksum; ++p) 
 353         pMFHead ->checksum ^= *p; 
 355     FILE *fd = fopen(filename.fn_str(), "rb"); 
 359     wxChar tempFileBuf[256]; 
 360     wxGetTempFileName(wxT("mf"), tempFileBuf); 
 361     FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb"); 
 364     fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle); 
 366     // Calculate origin and extent 
 369     int extentX = x2 - x1; 
 370     int extentY = (y2 - y1); 
 372     // Read metafile header and write 
 373     METAHEADER metaHeader; 
 374     fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd); 
 376     if (useOriginAndExtent) 
 377         metaHeader.mtSize += 15; 
 379         metaHeader.mtSize += 5; 
 381     fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle); 
 383     // Write SetMapMode, SetWindowOrigin and SetWindowExt records 
 385     char originBuffer[10]; 
 386     char extentBuffer[10]; 
 387     METARECORD *modeRecord = (METARECORD *)&modeBuffer; 
 389     METARECORD *originRecord = (METARECORD *)&originBuffer; 
 390     METARECORD *extentRecord = (METARECORD *)&extentBuffer; 
 392     modeRecord->rdSize = 4; 
 393     modeRecord->rdFunction = META_SETMAPMODE; 
 394     modeRecord->rdParm[0] = MM_ANISOTROPIC; 
 396     originRecord->rdSize = 5; 
 397     originRecord->rdFunction = META_SETWINDOWORG; 
 398     originRecord->rdParm[0] = originY; 
 399     originRecord->rdParm[1] = originX; 
 401     extentRecord->rdSize = 5; 
 402     extentRecord->rdFunction = META_SETWINDOWEXT; 
 403     extentRecord->rdParm[0] = extentY; 
 404     extentRecord->rdParm[1] = extentX; 
 406     fwrite((void *)modeBuffer, sizeof(char), 8, fHandle); 
 408     if (useOriginAndExtent) 
 410         fwrite((void *)originBuffer, sizeof(char), 10, fHandle); 
 411         fwrite((void *)extentBuffer, sizeof(char), 10, fHandle); 
 425     wxRemoveFile(filename); 
 426     wxCopyFile(tempFileBuf, filename); 
 427     wxRemoveFile(tempFileBuf); 
 432 #endif // wxUSE_METAFILE