X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e306597309a120f2ae91385c731a5cb2722c52aa..a4f4d548ce0d3533fe9e84d812643cc7c21dd580:/src/mac/carbon/metafile.cpp diff --git a/src/mac/carbon/metafile.cpp b/src/mac/carbon/metafile.cpp index ddbfb8402f..3dd6682e84 100644 --- a/src/mac/carbon/metafile.cpp +++ b/src/mac/carbon/metafile.cpp @@ -1,58 +1,198 @@ ///////////////////////////////////////////////////////////////////////////// // Name: metafile.cpp // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional. -// Author: AUTHOR +// Author: Stefan Csomor // Modified by: // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) Stefan Csomor +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "metafile.h" +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop #endif -#include "wx/object.h" -#include "wx/string.h" -#include "wx/dc.h" -#include "wx/stubs/metafile.h" +#if wxUSE_METAFILE + +#ifndef WX_PRECOMP +#include "wx/utils.h" +#include "wx/app.h" +#endif + +#include "wx/metafile.h" #include "wx/clipbrd.h" +#include "wx/mac/private.h" + +#include +#include + extern bool wxClipboardIsOpen; -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxMetaFile, wxObject) -IMPLEMENT_ABSTRACT_CLASS(wxMetaFileDC, wxDC) +IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject) +IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC) + +class wxMetafileRefData: public wxGDIRefData +{ + friend class WXDLLEXPORT wxMetafile; +public: + wxMetafileRefData(void); + ~wxMetafileRefData(void); + +private: + PicHandle m_metafile; +#if wxMAC_USE_CORE_GRAPHICS + QDPictRef m_qdPictRef ; +#endif +}; + + +/* + * Metafiles + * Currently, the only purpose for making a metafile is to put + * it on the clipboard. + */ + +wxMetafileRefData::wxMetafileRefData(void) +{ + m_metafile = 0; +#if wxMAC_USE_CORE_GRAPHICS + m_qdPictRef = NULL ; +#endif +} + +wxMetafileRefData::~wxMetafileRefData(void) +{ + if (m_metafile) + { + KillPicture( (PicHandle) m_metafile ) ; + m_metafile = 0; +#if wxMAC_USE_CORE_GRAPHICS + QDPictRelease( m_qdPictRef ) ; + m_qdPictRef = NULL ; #endif + } +} wxMetaFile::wxMetaFile(const wxString& file) { - // TODO + m_refData = new wxMetafileRefData; + + M_METAFILEDATA->m_metafile = 0; + wxASSERT_MSG( file.empty() , wxT("no file based metafile support yet") ) ; +/* + if (!file.IsNull() && (file.Cmp("") == 0)) + M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile(file); +*/ } wxMetaFile::~wxMetaFile() { - // TODO +} + +bool wxMetaFile::Ok() const +{ + return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != 0)); +} + +WXHMETAFILE wxMetaFile::GetHMETAFILE() const +{ + return (WXHMETAFILE) M_METAFILEDATA->m_metafile; } bool wxMetaFile::SetClipboard(int width, int height) { - bool alreadyOpen=wxClipboardOpen(); + bool success = true; + +#if wxUSE_DRAG_AND_DROP + //TODO finishi this port , we need the data obj first + if (!m_refData) + return false; + + bool alreadyOpen=wxTheClipboard->IsOpened() ; + if (!alreadyOpen) + { + wxTheClipboard->Open(); + wxTheClipboard->Clear(); + } + wxDataObject *data = + new wxMetafileDataObject( *this) ; + success = wxTheClipboard->SetData(data); if (!alreadyOpen) + wxTheClipboard->Close(); +#endif + + return success; +} + +void wxMetafile::SetHMETAFILE(WXHMETAFILE mf) +{ + UnRef() ; + + m_refData = new wxMetafileRefData; + + M_METAFILEDATA->m_metafile = (PicHandle) mf; +#if wxMAC_USE_CORE_GRAPHICS + size_t sz = GetHandleSize( (Handle) M_METAFILEDATA->m_metafile ) ; + wxMemoryBuffer* membuf = new wxMemoryBuffer( sz ) ; + void * data = membuf->GetWriteBuf(sz) ; + memcpy( data , *M_METAFILEDATA->m_metafile , sz ) ; + membuf->UngetWriteBuf(sz) ; + CGDataProviderRef provider = CGDataProviderCreateWithData( membuf , data , sz , + wxMacMemoryBufferReleaseProc ) ; + M_METAFILEDATA->m_qdPictRef = NULL ; + if ( provider != NULL ) { - wxOpenClipboard(); - if (!wxEmptyClipboard()) return FALSE; + M_METAFILEDATA->m_qdPictRef = QDPictCreateWithProvider( provider ) ; + CGDataProviderRelease( provider ) ; } - bool success = wxSetClipboardData(wxDF_METAFILE,this, width,height); - if (!alreadyOpen) wxCloseClipboard(); - return (bool) success; +#endif } bool wxMetaFile::Play(wxDC *dc) { - // TODO - return FALSE; + if (!m_refData) + return false; + + if (!dc->Ok() ) + return false; + + { +#if wxMAC_USE_CORE_GRAPHICS + QDPictRef cgPictRef = M_METAFILEDATA->m_qdPictRef ; + CGContextRef cg = ((wxMacCGContext*)(dc->GetGraphicContext()))->GetNativeContext() ; + CGRect bounds = QDPictGetBounds( cgPictRef ) ; + + CGContextSaveGState(cg); + CGContextTranslateCTM(cg, 0 , bounds.size.width ); + CGContextScaleCTM(cg, 1, -1); + QDPictDrawToCGContext( cg , bounds , cgPictRef ) ; + CGContextRestoreGState( cg ) ; +#else + PicHandle pict = (PicHandle) GetHMETAFILE() ; + wxMacPortSetter helper( dc ) ; + DrawPicture( pict , &(**pict).picFrame ) ; +#endif + } + return true; +} + +wxSize wxMetaFile::GetSize() const +{ + wxSize size = wxDefaultSize ; + if ( Ok() ) + { + PicHandle pict = (PicHandle) GetHMETAFILE() ; + Rect &r = (**pict).picFrame ; + size.x = r.right - r.left ; + size.y = r.bottom - r.top ; + } + + return size; } /* @@ -60,180 +200,71 @@ bool wxMetaFile::Play(wxDC *dc) * */ -// Original constructor that does not takes origin and extent. If you use this, -// *DO* give origin/extent arguments to wxMakeMetaFilePlaceable. -wxMetaFileDC::wxMetaFileDC(const wxString& file) -{ - // TODO -} - // New constructor that takes origin and extent. If you use this, don't // give origin/extent arguments to wxMakeMetaFilePlaceable. -wxMetaFileDC::wxMetaFileDC(const wxString& file, int xext, int yext, int xorg, int yorg) + +wxMetaFileDC::wxMetaFileDC(const wxString& filename , + int width , int height , + const wxString& WXUNUSED(description) ) { - // TODO + wxASSERT_MSG( width == 0 || height == 0 , _T("no arbitration of metafilesize supported") ) ; + wxASSERT_MSG( filename.empty() , _T("no file based metafile support yet")) ; + + m_metaFile = new wxMetaFile(filename) ; +#if wxMAC_USE_CORE_GRAPHICS +#else + Rect r={0,0,height,width} ; + + RectRgn( (RgnHandle) m_macBoundaryClipRgn , &r ) ; + CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; + + m_metaFile->SetHMETAFILE( (WXHMETAFILE) OpenPicture( &r ) ) ; + ::GetPort( (GrafPtr*) &m_macPort ) ; + m_ok = true ; +#endif + SetMapMode(wxMM_TEXT); } wxMetaFileDC::~wxMetaFileDC() { } -void wxMetaFileDC::GetTextExtent(const wxString& string, float *x, float *y, - float *descent, float *externalLeading, wxFont *theFont, bool use16bit) +void wxMetaFileDC::DoGetSize(int *width, int *height) const { - // TODO + wxCHECK_RET( m_metaFile , _T("GetSize() doesn't work without a metafile") ); + + wxSize sz = m_metaFile->GetSize() ; + if (width) (*width) = sz.x; + if (height) (*height) = sz.y; } wxMetaFile *wxMetaFileDC::Close() { - // TODO - return NULL; + ClosePicture() ; + return m_metaFile; } -void wxMetaFileDC::SetMapMode(int mode) +#if wxUSE_DATAOBJ +size_t wxMetafileDataObject::GetDataSize() const { - // TODO + return GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() ) ; } -#if 0 - -#ifdef __WIN32__ -struct RECT32 +bool wxMetafileDataObject::GetDataHere(void *buf) const { - short left; - short top; - short right; - short bottom; -}; - -struct mfPLACEABLEHEADER { - DWORD key; - short hmf; - RECT32 bbox; - WORD inch; - DWORD reserved; - WORD checksum; -}; -#else -struct mfPLACEABLEHEADER { - DWORD key; - HANDLE hmf; - RECT bbox; - WORD inch; - DWORD reserved; - WORD checksum; -}; -#endif - -/* - * Pass filename of existing non-placeable metafile, and bounding box. - * Adds a placeable metafile header, sets the mapping mode to anisotropic, - * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode. - * - */ - -bool wxMakeMetaFilePlaceable(const wxString& filename, float scale) -{ - return wxMakeMetaFilePlaceable(filename, 0, 0, 0, 0, scale, FALSE); -} - -bool wxMakeMetaFilePlaceable(const wxString& filename, int x1, int y1, int x2, int y2, float scale, bool useOriginAndExtent) -{ - // I'm not sure if this is the correct way of suggesting a scale - // to the client application, but it's the only way I can find. - int unitsPerInch = (int)(576/scale); - - mfPLACEABLEHEADER header; - header.key = 0x9AC6CDD7L; - header.hmf = 0; - header.bbox.left = (int)(x1); - header.bbox.top = (int)(y1); - header.bbox.right = (int)(x2); - header.bbox.bottom = (int)(y2); - header.inch = unitsPerInch; - header.reserved = 0; - - // Calculate checksum - WORD *p; - mfPLACEABLEHEADER *pMFHead = &header; - for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; - p < (WORD *)&pMFHead ->checksum; ++p) - pMFHead ->checksum ^= *p; - - FILE *fd = fopen((char *)(const char *)filename, "rb"); - if (!fd) return FALSE; - - char tempFileBuf[256]; - wxGetTempFileName("mf", tempFileBuf); - FILE *fHandle = fopen(tempFileBuf, "wb"); - if (!fHandle) - return FALSE; - fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle); - - // Calculate origin and extent - int originX = x1; - int originY = y1; - int extentX = x2 - x1; - int extentY = (y2 - y1); - - // Read metafile header and write - METAHEADER metaHeader; - fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd); - - if (useOriginAndExtent) - metaHeader.mtSize += 15; - else - metaHeader.mtSize += 5; - - fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle); - - // Write SetMapMode, SetWindowOrigin and SetWindowExt records - char modeBuffer[8]; - char originBuffer[10]; - char extentBuffer[10]; - METARECORD *modeRecord = (METARECORD *)&modeBuffer; - - METARECORD *originRecord = (METARECORD *)&originBuffer; - METARECORD *extentRecord = (METARECORD *)&extentBuffer; - - modeRecord->rdSize = 4; - modeRecord->rdFunction = META_SETMAPMODE; - modeRecord->rdParm[0] = wxMM_ANISOTROPIC; - - originRecord->rdSize = 5; - originRecord->rdFunction = META_SETWINDOWORG; - originRecord->rdParm[0] = originY; - originRecord->rdParm[1] = originX; - - extentRecord->rdSize = 5; - extentRecord->rdFunction = META_SETWINDOWEXT; - extentRecord->rdParm[0] = extentY; - extentRecord->rdParm[1] = extentX; - - fwrite((void *)modeBuffer, sizeof(char), 8, fHandle); - - if (useOriginAndExtent) - { - fwrite((void *)originBuffer, sizeof(char), 10, fHandle); - fwrite((void *)extentBuffer, sizeof(char), 10, fHandle); - } - - int ch = -2; - while (ch != EOF) - { - ch = getc(fd); - if (ch != EOF) - { - putc(ch, fHandle); - } - } - fclose(fHandle); - fclose(fd); - wxRemoveFile(filename); - wxCopyFile(tempFileBuf, filename); - wxRemoveFile(tempFileBuf); - return TRUE; + memcpy( buf , (*(PicHandle)(*((wxMetafile*)&m_metafile)).GetHMETAFILE()) , + GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() ) ) ; + return true ; } +bool wxMetafileDataObject::SetData(size_t len, const void *buf) +{ + Handle handle = NewHandle( len ) ; + SetHandleSize( handle , len ) ; + memcpy( *handle , buf , len ) ; + m_metafile.SetHMETAFILE( (WXHMETAFILE) handle ) ; + return true ; +} #endif +#endif