X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8907154c1a8a6882c6797d1f16393ddfb23e7f3a..5c7b506103cfc078a821860766e31c47d595e07f:/src/mac/carbon/metafile.cpp diff --git a/src/mac/carbon/metafile.cpp b/src/mac/carbon/metafile.cpp index 3dd6682e84..73d5b77f9a 100644 --- a/src/mac/carbon/metafile.cpp +++ b/src/mac/carbon/metafile.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: metafile.cpp +// Name: src/mac/carbon/metafile.cpp // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional. // Author: Stefan Csomor // Modified by: @@ -8,120 +8,200 @@ // Copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// +// Currently, the only purpose for making a metafile +// is to put it on the clipboard. -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" -#ifdef __BORLANDC__ -#pragma hdrstop -#endif +#include "wx/wxprec.h" #if wxUSE_METAFILE #ifndef WX_PRECOMP -#include "wx/utils.h" -#include "wx/app.h" + #include "wx/utils.h" + #include "wx/app.h" #endif #include "wx/metafile.h" #include "wx/clipbrd.h" - -#include "wx/mac/private.h" +#include "wx/mac/uma.h" +#include "wx/graphics.h" +#include "wx/mac/carbon/metafile.h" #include #include -extern bool wxClipboardIsOpen; - IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject) IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC) +IMPLEMENT_ABSTRACT_CLASS(wxMetafileDCImpl, wxGCDCImpl) -class wxMetafileRefData: public wxGDIRefData +#define M_METAFILEREFDATA( a ) ((wxMetafileRefData*)(a).GetRefData()) + +class wxMetafileRefData : public wxGDIRefData { - friend class WXDLLEXPORT wxMetafile; public: - wxMetafileRefData(void); - ~wxMetafileRefData(void); + // default ctor needed for CreateGDIRefData(), must be initialized later + wxMetafileRefData() { Init(); } + + // creates a metafile from memory, assumes ownership + wxMetafileRefData(CFDataRef data); + + // prepares a recording metafile + wxMetafileRefData( int width, int height); + + // prepares a metafile to be read from a file (if filename is not empty) + wxMetafileRefData( const wxString& filename); + virtual ~wxMetafileRefData(); + + virtual bool IsOk() const { return m_data != NULL; } + + void Init(); + + int GetWidth() const { return m_width; } + int GetHeight() const { return m_height; } + + CGPDFDocumentRef GetPDFDocument() const { return m_pdfDoc; } + void UpdateDocumentFromData() ; + + const wxCFDataRef& GetData() const { return m_data; } + CGContextRef GetContext() const { return m_context; } + + // ends the recording + void Close(); private: - PicHandle m_metafile; -#if wxMAC_USE_CORE_GRAPHICS - QDPictRef m_qdPictRef ; -#endif + wxCFDataRef m_data; + wxCFRef m_pdfDoc; + CGContextRef m_context; + + int m_width ; + int m_height ; }; +wxMetafileRefData::wxMetafileRefData(CFDataRef data) : + m_data(data) +{ + Init(); + UpdateDocumentFromData(); +} -/* - * Metafiles - * Currently, the only purpose for making a metafile is to put - * it on the clipboard. - */ +wxMetafileRefData::wxMetafileRefData( const wxString& filename ) +{ + Init(); -wxMetafileRefData::wxMetafileRefData(void) + if ( !filename.empty() ) + { + wxCFRef cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(filename))); + CFStringNormalize(cfMutableString,kCFStringNormalizationFormD); + wxCFRef url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false)); + m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url)); + } +} + + +wxMetafileRefData::wxMetafileRefData( int width, int height) { - m_metafile = 0; -#if wxMAC_USE_CORE_GRAPHICS - m_qdPictRef = NULL ; -#endif + Init(); + + m_width = width; + m_height = height; + + CGRect r = CGRectMake( 0 , 0 , width , height ); + + CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0); + m_data.reset(data); + CGDataConsumerRef dataConsumer = wxMacCGDataConsumerCreateWithCFData(data); + m_context = CGPDFContextCreate( dataConsumer, (width != 0 && height != 0) ? &r : NULL , NULL ); + CGDataConsumerRelease( dataConsumer ); + if ( m_context ) + { + CGPDFContextBeginPage(m_context, NULL); + + CGColorSpaceRef genericColorSpace = wxMacGetGenericRGBColorSpace(); + + CGContextSetFillColorSpace( m_context, genericColorSpace ); + CGContextSetStrokeColorSpace( m_context, genericColorSpace ); + + CGContextTranslateCTM( m_context , 0 , height ) ; + CGContextScaleCTM( m_context , 1 , -1 ) ; + } } -wxMetafileRefData::~wxMetafileRefData(void) +wxMetafileRefData::~wxMetafileRefData() { - if (m_metafile) +} + +void wxMetafileRefData::Init() +{ + m_context = NULL; + m_width = -1; + m_height = -1; +} + +void wxMetafileRefData::Close() +{ + CGPDFContextEndPage(m_context); + + CGContextRelease(m_context); + m_context = NULL; + + UpdateDocumentFromData(); +} + +void wxMetafileRefData::UpdateDocumentFromData() +{ + wxCFRef provider(wxMacCGDataProviderCreateWithCFData(m_data)); + m_pdfDoc.reset(CGPDFDocumentCreateWithProvider(provider)); + if ( m_pdfDoc != NULL ) { - KillPicture( (PicHandle) m_metafile ) ; - m_metafile = 0; -#if wxMAC_USE_CORE_GRAPHICS - QDPictRelease( m_qdPictRef ) ; - m_qdPictRef = NULL ; -#endif + CGPDFPageRef page = CGPDFDocumentGetPage( m_pdfDoc, 1 ); + CGRect rect = CGPDFPageGetBoxRect ( page, kCGPDFMediaBox); + m_width = wx_static_cast(int, rect.size.width); + m_height = wx_static_cast(int, rect.size.height); } } wxMetaFile::wxMetaFile(const wxString& file) { - 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); -*/ + m_refData = new wxMetafileRefData(file); } wxMetaFile::~wxMetaFile() { } -bool wxMetaFile::Ok() const +wxGDIRefData *wxMetaFile::CreateGDIRefData() const +{ + return new wxMetafileRefData; +} + +wxGDIRefData *wxMetaFile::CloneGDIRefData(const wxGDIRefData *data) const { - return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != 0)); + return new wxMetafileRefData(*wx_static_cast(const wxMetafileRefData *, data)); } WXHMETAFILE wxMetaFile::GetHMETAFILE() const { - return (WXHMETAFILE) M_METAFILEDATA->m_metafile; + return (WXHMETAFILE) (CFDataRef) M_METAFILEDATA->GetData(); } -bool wxMetaFile::SetClipboard(int width, int height) +bool wxMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height)) { bool success = true; #if wxUSE_DRAG_AND_DROP - //TODO finishi this port , we need the data obj first - if (!m_refData) + if (m_refData == NULL) return false; - bool alreadyOpen=wxTheClipboard->IsOpened() ; + bool alreadyOpen = wxTheClipboard->IsOpened(); if (!alreadyOpen) { wxTheClipboard->Open(); wxTheClipboard->Clear(); } - wxDataObject *data = - new wxMetafileDataObject( *this) ; - success = wxTheClipboard->SetData(data); + + wxDataObject *data = new wxMetafileDataObject( *this ); + success = wxTheClipboard->SetData( data ); if (!alreadyOpen) wxTheClipboard->Close(); #endif @@ -131,139 +211,155 @@ bool wxMetaFile::SetClipboard(int width, int height) 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 ) - { - M_METAFILEDATA->m_qdPictRef = QDPictCreateWithProvider( provider ) ; - CGDataProviderRelease( provider ) ; - } -#endif + UnRef(); + + m_refData = new wxMetafileRefData((CFDataRef)mf); } +#ifndef __LP64__ +void wxMetafile::SetPICT(void* pictHandle) +{ + UnRef(); + + Handle picHandle = (Handle) pictHandle; + HLock(picHandle); + CFDataRef data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) *picHandle, GetHandleSize(picHandle), kCFAllocatorNull); + wxCFRef provider(wxMacCGDataProviderCreateWithCFData(data)); + QDPictRef pictRef = QDPictCreateWithProvider(provider); + CGRect rect = QDPictGetBounds(pictRef); + m_refData = new wxMetafileRefData(wx_static_cast(int, rect.size.width), + wx_static_cast(int, rect.size.height)); + QDPictDrawToCGContext( ((wxMetafileRefData*) m_refData)->GetContext(), rect, pictRef ); + CFRelease( data ); + QDPictRelease( pictRef ); + ((wxMetafileRefData*) m_refData)->Close(); +} +#endif + bool wxMetaFile::Play(wxDC *dc) { if (!m_refData) return false; - if (!dc->Ok() ) + if (!dc->IsOk()) 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 + wxDCImpl *impl = dc->GetImpl(); + wxGCDCImpl *gc_impl = wxDynamicCast(impl, wxGCDCImpl); + if (gc_impl) + { + CGContextRef cg = (CGContextRef) (gc_impl->GetGraphicsContext()->GetNativeContext()); + CGPDFDocumentRef doc = M_METAFILEDATA->GetPDFDocument(); + CGPDFPageRef page = CGPDFDocumentGetPage( doc, 1 ); + wxMacCGContextStateSaver save(cg); + CGContextDrawPDFPage( cg, page ); + } +// CGContextTranslateCTM( cg, 0, bounds.size.width ); +// CGContextScaleCTM( cg, 1, -1 ); } + return true; } wxSize wxMetaFile::GetSize() const { - wxSize size = wxDefaultSize ; - if ( Ok() ) + wxSize dataSize = wxDefaultSize; + + if (Ok()) { - PicHandle pict = (PicHandle) GetHMETAFILE() ; - Rect &r = (**pict).picFrame ; - size.x = r.right - r.left ; - size.y = r.bottom - r.top ; + dataSize.x = M_METAFILEDATA->GetWidth(); + dataSize.y = M_METAFILEDATA->GetHeight(); } - return size; + return dataSize; } -/* - * Metafile device context - * - */ +// Metafile device context // New constructor that takes origin and extent. If you use this, don't // give origin/extent arguments to wxMakeMetaFilePlaceable. -wxMetaFileDC::wxMetaFileDC(const wxString& filename , - int width , int height , - const wxString& WXUNUSED(description) ) +wxMetafileDCImpl::wxMetafileDCImpl( + wxDC *owner, + const wxString& filename, + int width, int height, + const wxString& WXUNUSED(description) ) : + wxGCDCImpl( owner ) { - wxASSERT_MSG( width == 0 || height == 0 , _T("no arbitration of metafilesize supported") ) ; - wxASSERT_MSG( filename.empty() , _T("no file based metafile support yet")) ; + wxASSERT_MSG( width != 0 || height != 0, wxT("no arbitration of metafile size supported") ); + wxASSERT_MSG( filename.empty(), wxT("no file based metafile support yet")); - m_metaFile = new wxMetaFile(filename) ; -#if wxMAC_USE_CORE_GRAPHICS -#else - Rect r={0,0,height,width} ; + m_metaFile = new wxMetaFile( filename ); + wxMetafileRefData* metafiledata = new wxMetafileRefData(width, height); + m_metaFile->UnRef(); + m_metaFile->SetRefData( metafiledata ); - RectRgn( (RgnHandle) m_macBoundaryClipRgn , &r ) ; - CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ; + SetGraphicsContext( wxGraphicsContext::CreateFromNative(metafiledata->GetContext())); + m_ok = (m_graphicContext != NULL) ; - m_metaFile->SetHMETAFILE( (WXHMETAFILE) OpenPicture( &r ) ) ; - ::GetPort( (GrafPtr*) &m_macPort ) ; - m_ok = true ; -#endif - SetMapMode(wxMM_TEXT); + SetMapMode( wxMM_TEXT ); } -wxMetaFileDC::~wxMetaFileDC() +wxMetafileDCImpl::~wxMetafileDCImpl() { } -void wxMetaFileDC::DoGetSize(int *width, int *height) const +void wxMetafileDCImpl::DoGetSize(int *width, int *height) const { - wxCHECK_RET( m_metaFile , _T("GetSize() doesn't work without a metafile") ); + wxCHECK_RET( m_metaFile, wxT("GetSize() doesn't work without a metafile") ); - wxSize sz = m_metaFile->GetSize() ; - if (width) (*width) = sz.x; - if (height) (*height) = sz.y; + wxSize sz = m_metaFile->GetSize(); + if (width) + (*width) = sz.x; + if (height) + (*height) = sz.y; } -wxMetaFile *wxMetaFileDC::Close() +wxMetaFile *wxMetafileDCImpl::Close() { - ClosePicture() ; + delete m_graphicContext; + m_graphicContext = NULL; + m_ok = false; + + M_METAFILEREFDATA(*m_metaFile)->Close(); + return m_metaFile; } #if wxUSE_DATAOBJ size_t wxMetafileDataObject::GetDataSize() const { - return GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() ) ; + CFIndex length = 0; + wxMetafileRefData* refData = M_METAFILEREFDATA(m_metafile); + if ( refData ) + length = refData->GetData().GetLength(); + return length; } bool wxMetafileDataObject::GetDataHere(void *buf) const { - memcpy( buf , (*(PicHandle)(*((wxMetafile*)&m_metafile)).GetHMETAFILE()) , - GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() ) ) ; - return true ; + bool result = false; + + wxMetafileRefData* refData = M_METAFILEREFDATA(m_metafile); + if ( refData ) + { + CFIndex length = refData->GetData().GetLength(); + if ( length > 0 ) + { + result = true ; + refData->GetData().GetBytes(CFRangeMake(0,length), (UInt8 *) buf); + } + } + return result; } 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 ; + wxMetafileRefData* metafiledata = new wxMetafileRefData(wxCFRefFromGet(wxCFDataRef((UInt8*)buf, len).get())); + m_metafile.UnRef(); + m_metafile.SetRefData( metafiledata ); + return true; } #endif