]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/metafile.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   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" 
  26 #include "wx/metafile.h" 
  27 #include "wx/clipbrd.h" 
  28 #include "wx/os2/private.h" 
  33 extern bool wxClipboardIsOpen
; 
  35 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
) 
  36 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
) 
  40  * Currently, the only purpose for making a metafile is to put 
  41  * it on the clipboard. 
  44 wxMetafileRefData::wxMetafileRefData(void) 
  47     m_windowsMappingMode 
= wxMM_ANISOTROPIC
; 
  50 wxMetafileRefData::~wxMetafileRefData(void) 
  54 // TODO: DeleteMetaFile((HMETAFILE) m_metafile); 
  59 wxMetafile::wxMetafile(const wxString
& file
) 
  61     m_refData 
= new wxMetafileRefData
; 
  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); 
  69 wxMetafile::~wxMetafile(void) 
  73 bool wxMetafile::SetClipboard(int width
, int height
) 
  78     bool alreadyOpen
=wxClipboardOpen(); 
  82         if (!wxEmptyClipboard()) return FALSE
; 
  84     bool success 
= wxSetClipboardData(wxDF_METAFILE
, this, width
,height
); 
  85     if (!alreadyOpen
) wxCloseClipboard(); 
  86     return (bool) success
; 
  89 bool wxMetafile::Play(wxDC 
*dc
) 
  96  //   if (dc->GetHDC() && M_METAFILEDATA->m_metafile) 
  97  //       PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile); 
 104 void wxMetafile::SetHMETAFILE(WXHANDLE mf
) 
 107         m_refData 
= new wxMetafileRefData
; 
 109     M_METAFILEDATA
->m_metafile 
= mf
; 
 112 void wxMetafile::SetWindowsMappingMode(int mm
) 
 115         m_refData 
= new wxMetafileRefData
; 
 117     M_METAFILEDATA
->m_windowsMappingMode 
= mm
; 
 121  * Metafile device context 
 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
) 
 136   if (!file
.IsNull() && wxFileExists(file
)) 
 141   if (!file.IsNull() && (file != wxT(""))) 
 142     m_hDC = (WXHDC) CreateMetaFile(file); 
 144     m_hDC = (WXHDC) CreateMetaFile(NULL); 
 147   m_ok 
= (m_hDC 
!= (WXHDC
) 0) ; 
 149   // Actual Windows mapping mode, for future reference. 
 150   m_windowsMappingMode 
= wxMM_TEXT
; 
 152   SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct) 
 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
) 
 163   if (file 
!= wxT("") && wxFileExists(file
)) wxRemoveFile(file
); 
 164 //  m_hDC = (WXHDC) CreateMetaFile(file); 
 168 //  ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL); 
 169 //  ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL); 
 171   // Actual Windows mapping mode, for future reference. 
 172   m_windowsMappingMode 
= wxMM_ANISOTROPIC
; 
 174   SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct) 
 177 wxMetafileDC::~wxMetafileDC(void) 
 182 void wxMetafileDC::GetTextExtent(const wxString
& string
, long *x
, long *y
, 
 183                                  long *descent
, long *externalLeading
, wxFont 
*theFont
, bool use16bit
) const 
 185   wxFont 
*fontToUse 
= theFont
; 
 187     fontToUse 
= (wxFont
*) &m_font
; 
 191   HDC dc = GetDC(NULL); 
 195   GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); 
 196   GetTextMetrics(dc, &tm); 
 205       *descent = tm.tmDescent; 
 206   if ( externalLeading ) 
 207       *externalLeading = tm.tmExternalLeading; 
 211 wxMetafile 
*wxMetafileDC::Close(void) 
 213   SelectOldObjects(m_hDC
); 
 214   HANDLE mf 
= 0; // TODO: CloseMetaFile((HDC) m_hDC); 
 218     wxMetafile 
*wx_mf 
= new wxMetafile
; 
 219     wx_mf
->SetHMETAFILE((WXHANDLE
) mf
); 
 220     wx_mf
->SetWindowsMappingMode(m_windowsMappingMode
); 
 226 void wxMetafileDC::SetMapMode(int mode
) 
 228   m_mappingMode 
= mode
; 
 230 //  int pixel_width = 0; 
 231 //  int pixel_height = 0; 
 233 //  int mm_height = 0; 
 235   float mm2pixelsX 
= 10.0; 
 236   float mm2pixelsY 
= 10.0; 
 242       m_logicalScaleX 
= (float)(twips2mm 
* mm2pixelsX
); 
 243       m_logicalScaleY 
= (float)(twips2mm 
* mm2pixelsY
); 
 248       m_logicalScaleX 
= (float)(pt2mm 
* mm2pixelsX
); 
 249       m_logicalScaleY 
= (float)(pt2mm 
* mm2pixelsY
); 
 254       m_logicalScaleX 
= mm2pixelsX
; 
 255       m_logicalScaleY 
= mm2pixelsY
; 
 260       m_logicalScaleX 
= (float)(mm2pixelsX
/10.0); 
 261       m_logicalScaleY 
= (float)(mm2pixelsY
/10.0); 
 267       m_logicalScaleX 
= 1.0; 
 268       m_logicalScaleY 
= 1.0; 
 285 struct mfPLACEABLEHEADER 
{ 
 294 struct mfPLACEABLEHEADER 
{ 
 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. 
 311 bool wxMakeMetafilePlaceable(const wxString
& filename
, float scale
) 
 313   return wxMakeMetafilePlaceable(filename
, 0, 0, 0, 0, scale
, FALSE
); 
 316 bool wxMakeMetafilePlaceable(const wxString
& filename
, int x1
, int y1
, int x2
, int y2
, float scale
, bool useOriginAndExtent
) 
 318 // TODO:  the OS/2 PM/MM way to do this 
 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); 
 324   mfPLACEABLEHEADER header; 
 325   header.key = 0x9AC6CDD7L; 
 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; 
 334   // Calculate checksum 
 336   mfPLACEABLEHEADER *pMFHead = &header; 
 337   for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; 
 338         p < (WORD *)&pMFHead ->checksum; ++p) 
 339        pMFHead ->checksum ^= *p; 
 341   FILE *fd = fopen(filename.fn_str(), "rb"); 
 342   if (!fd) return FALSE; 
 344   wxChar tempFileBuf[256]; 
 345   wxGetTempFileName(wxT("mf"), tempFileBuf); 
 346   FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb"); 
 349   fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle); 
 351   // Calculate origin and extent 
 354   int extentX = x2 - x1; 
 355   int extentY = (y2 - y1); 
 357   // Read metafile header and write 
 358   METAHEADER metaHeader; 
 359   fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd); 
 361   if (useOriginAndExtent) 
 362     metaHeader.mtSize += 15; 
 364     metaHeader.mtSize += 5; 
 366   fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle); 
 368   // Write SetMapMode, SetWindowOrigin and SetWindowExt records 
 370   char originBuffer[10]; 
 371   char extentBuffer[10]; 
 372   METARECORD *modeRecord = (METARECORD *)&modeBuffer; 
 374   METARECORD *originRecord = (METARECORD *)&originBuffer; 
 375   METARECORD *extentRecord = (METARECORD *)&extentBuffer; 
 377   modeRecord->rdSize = 4; 
 378   modeRecord->rdFunction = META_SETMAPMODE; 
 379   modeRecord->rdParm[0] = MM_ANISOTROPIC; 
 381   originRecord->rdSize = 5; 
 382   originRecord->rdFunction = META_SETWINDOWORG; 
 383   originRecord->rdParm[0] = originY; 
 384   originRecord->rdParm[1] = originX; 
 386   extentRecord->rdSize = 5; 
 387   extentRecord->rdFunction = META_SETWINDOWEXT; 
 388   extentRecord->rdParm[0] = extentY; 
 389   extentRecord->rdParm[1] = extentX; 
 391   fwrite((void *)modeBuffer, sizeof(char), 8, fHandle); 
 393   if (useOriginAndExtent) 
 395     fwrite((void *)originBuffer, sizeof(char), 10, fHandle); 
 396     fwrite((void *)extentBuffer, sizeof(char), 10, fHandle); 
 410   wxRemoveFile(filename); 
 411   wxCopyFile(tempFileBuf, filename); 
 412   wxRemoveFile(tempFileBuf); 
 417 #endif // wxUSE_METAFILE