]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/metafile.cpp
   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 wxGDIRefData 
*wxMetafile::CreateGDIRefData() const 
  71     return new wxMetafileRefData
; 
  74 wxGDIRefData 
*wxMetafile::CloneGDIRefData(const wxGDIRefData 
*data
) const 
  76     return new wxMetafileRefData(*static_cast<const wxMetafileRefData 
*>(data
)); 
  79 bool wxMetafile::SetClipboard(int width
, int height
) 
  89     bool alreadyOpen
=wxClipboardOpen(); 
  93         if (!wxEmptyClipboard()) return false; 
  95     bool success 
= wxSetClipboardData(wxDF_METAFILE
, this, width
,height
); 
  96     if (!alreadyOpen
) wxCloseClipboard(); 
  97     return (bool) success
; 
 101 bool wxMetafile::Play(wxDC 
*dc
) 
 106  //   if (dc->GetHDC() && M_METAFILEDATA->m_metafile) 
 107  //       PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile); 
 112 void wxMetafile::SetHMETAFILE(WXHANDLE mf
) 
 115         m_refData 
= new wxMetafileRefData
; 
 117     M_METAFILEDATA
->m_metafile 
= mf
; 
 120 void wxMetafile::SetWindowsMappingMode(int mm
) 
 123         m_refData 
= new wxMetafileRefData
; 
 125     M_METAFILEDATA
->m_windowsMappingMode 
= mm
; 
 129  * Metafile device context 
 133 // Original constructor that does not takes origin and extent. If you use this, 
 134 // *DO* give origin/extent arguments to wxMakeMetafilePlaceable. 
 135 wxMetafileDCImpl::wxMetafileDCImpl(wxDC 
*owner
, const wxString
& file
) 
 145   if (!file
.IsNull() && wxFileExists(file
)) 
 151     m_hDC = (WXHDC) CreateMetaFile(file); 
 153     m_hDC = (WXHDC) CreateMetaFile(NULL); 
 156   m_ok 
= (m_hDC 
!= (WXHDC
) 0) ; 
 158   // Actual Windows mapping mode, for future reference. 
 159   m_windowsMappingMode 
= wxMM_TEXT
; 
 161   SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct) 
 164 // New constructor that takes origin and extent. If you use this, don't 
 165 // give origin/extent arguments to wxMakeMetafilePlaceable. 
 166 wxMetafileDCImpl::wxMetafileDCImpl( wxDC 
*owner
, const wxString
& file
, 
 177     if (!file
.empty() && wxFileExists(file
)) 
 180 //  m_hDC = (WXHDC) CreateMetaFile(file); 
 184 //  ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL); 
 185 //  ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL); 
 187     // Actual Windows mapping mode, for future reference. 
 188     m_windowsMappingMode 
= wxMM_ANISOTROPIC
; 
 190     SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct) 
 193 wxMetafileDCImpl::~wxMetafileDCImpl(void) 
 198 void wxMetafileDCImpl::DoGetTextExtent(const wxString
& WXUNUSED(string
), 
 199                                      wxCoord 
*WXUNUSED(x
), 
 200                                      wxCoord 
*WXUNUSED(y
), 
 201                                      wxCoord 
*WXUNUSED(descent
), 
 202                                      wxCoord 
*WXUNUSED(externalLeading
), 
 203                                      const wxFont 
*theFont
) const 
 205     const wxFont 
*fontToUse 
= theFont
; 
 211     HDC dc = GetDC(NULL); 
 215     GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); 
 216     GetTextMetrics(dc, &tm); 
 225         *descent = tm.tmDescent; 
 226     if ( externalLeading ) 
 227         *externalLeading = tm.tmExternalLeading; 
 231 wxMetafile 
*wxMetafileDCImpl::Close(void) 
 233   SelectOldObjects(m_hDC
); 
 234   HANDLE mf 
= 0; // TODO: CloseMetaFile((HDC) m_hDC); 
 238     wxMetafile 
*wx_mf 
= new wxMetafile
; 
 239     wx_mf
->SetHMETAFILE((WXHANDLE
) mf
); 
 240     wx_mf
->SetWindowsMappingMode(m_windowsMappingMode
); 
 246 void wxMetafileDCImpl::SetMapMode(int mode
) 
 248   m_mappingMode 
= mode
; 
 250 //  int pixel_width = 0; 
 251 //  int pixel_height = 0; 
 253 //  int mm_height = 0; 
 255   float mm2pixelsX 
= 10.0; 
 256   float mm2pixelsY 
= 10.0; 
 262       m_logicalScaleX 
= (float)(twips2mm 
* mm2pixelsX
); 
 263       m_logicalScaleY 
= (float)(twips2mm 
* mm2pixelsY
); 
 268       m_logicalScaleX 
= (float)(pt2mm 
* mm2pixelsX
); 
 269       m_logicalScaleY 
= (float)(pt2mm 
* mm2pixelsY
); 
 274       m_logicalScaleX 
= mm2pixelsX
; 
 275       m_logicalScaleY 
= mm2pixelsY
; 
 280       m_logicalScaleX 
= (float)(mm2pixelsX
/10.0); 
 281       m_logicalScaleY 
= (float)(mm2pixelsY
/10.0); 
 287       m_logicalScaleX 
= 1.0; 
 288       m_logicalScaleY 
= 1.0; 
 305 struct mfPLACEABLEHEADER 
{ 
 314 struct mfPLACEABLEHEADER 
{ 
 325  * Pass filename of existing non-placeable metafile, and bounding box. 
 326  * Adds a placeable metafile header, sets the mapping mode to anisotropic, 
 327  * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode. 
 331 bool wxMakeMetafilePlaceable(const wxString
& filename
, float scale
) 
 333   return wxMakeMetafilePlaceable(filename
, 0, 0, 0, 0, scale
, FALSE
); 
 336 bool wxMakeMetafilePlaceable(const wxString
& WXUNUSED(filename
), 
 341                              float WXUNUSED(scale
), 
 342                              bool WXUNUSED(useOriginAndExtent
)) 
 344 // TODO:  the OS/2 PM/MM way to do this 
 346     // I'm not sure if this is the correct way of suggesting a scale 
 347     // to the client application, but it's the only way I can find. 
 348     int unitsPerInch = (int)(576/scale); 
 350     mfPLACEABLEHEADER header; 
 351     header.key = 0x9AC6CDD7L; 
 353     header.bbox.xLeft = (int)(x1); 
 354     header.bbox.yTop = (int)(y1); 
 355     header.bbox.xRight = (int)(x2); 
 356     header.bbox.yBottom = (int)(y2); 
 357     header.inch = unitsPerInch; 
 360     // Calculate checksum 
 362     mfPLACEABLEHEADER *pMFHead = &header; 
 363     for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; p < (WORD *)&pMFHead ->checksum; ++p) 
 364         pMFHead ->checksum ^= *p; 
 366     FILE *fd = fopen(filename.fn_str(), "rb"); 
 370     wxChar tempFileBuf[256]; 
 371     wxGetTempFileName(wxT("mf"), tempFileBuf); 
 372     FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb"); 
 375     fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle); 
 377     // Calculate origin and extent 
 380     int extentX = x2 - x1; 
 381     int extentY = (y2 - y1); 
 383     // Read metafile header and write 
 384     METAHEADER metaHeader; 
 385     fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd); 
 387     if (useOriginAndExtent) 
 388         metaHeader.mtSize += 15; 
 390         metaHeader.mtSize += 5; 
 392     fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle); 
 394     // Write SetMapMode, SetWindowOrigin and SetWindowExt records 
 396     char originBuffer[10]; 
 397     char extentBuffer[10]; 
 398     METARECORD *modeRecord = (METARECORD *)&modeBuffer; 
 400     METARECORD *originRecord = (METARECORD *)&originBuffer; 
 401     METARECORD *extentRecord = (METARECORD *)&extentBuffer; 
 403     modeRecord->rdSize = 4; 
 404     modeRecord->rdFunction = META_SETMAPMODE; 
 405     modeRecord->rdParm[0] = MM_ANISOTROPIC; 
 407     originRecord->rdSize = 5; 
 408     originRecord->rdFunction = META_SETWINDOWORG; 
 409     originRecord->rdParm[0] = originY; 
 410     originRecord->rdParm[1] = originX; 
 412     extentRecord->rdSize = 5; 
 413     extentRecord->rdFunction = META_SETWINDOWEXT; 
 414     extentRecord->rdParm[0] = extentY; 
 415     extentRecord->rdParm[1] = extentX; 
 417     fwrite((void *)modeBuffer, sizeof(char), 8, fHandle); 
 419     if (useOriginAndExtent) 
 421         fwrite((void *)originBuffer, sizeof(char), 10, fHandle); 
 422         fwrite((void *)extentBuffer, sizeof(char), 10, fHandle); 
 436     wxRemoveFile(filename); 
 437     wxCopyFile(tempFileBuf, filename); 
 438     wxRemoveFile(tempFileBuf); 
 443 #endif // wxUSE_METAFILE