+IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
+IMPLEMENT_ABSTRACT_CLASS(wxMetafileDCImpl, wxGCDCImpl)
+
+#define M_METAFILEREFDATA( a ) ((wxMetafileRefData*)(a).GetRefData())
+
+class wxMetafileRefData : public wxGDIRefData
+{
+public:
+ // 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:
+ wxCFDataRef m_data;
+ wxCFRef<CGPDFDocumentRef> m_pdfDoc;
+ CGContextRef m_context;
+
+ int m_width ;
+ int m_height ;
+};
+
+wxMetafileRefData::wxMetafileRefData(CFDataRef data) :
+ m_data(data)
+{
+ Init();
+ UpdateDocumentFromData();
+}
+
+wxMetafileRefData::wxMetafileRefData( const wxString& filename )
+{
+ Init();
+
+ if ( !filename.empty() )
+ {
+ wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(filename)));
+ CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
+ wxCFRef<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
+ m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url));
+ }
+}
+
+
+wxMetafileRefData::wxMetafileRefData( int width, int height)
+{
+ 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::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<CGDataProviderRef> provider(wxMacCGDataProviderCreateWithCFData(m_data));
+ m_pdfDoc.reset(CGPDFDocumentCreateWithProvider(provider));
+ if ( m_pdfDoc != NULL )
+ {
+ 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);
+ }
+}