PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Dependencies/wxWidgets/src/osx/carbon/metafile.cpp

https://github.com/goofoo/Helium
C++ | 365 lines | 267 code | 75 blank | 23 comment | 26 complexity | f8de6a7d496cce9eda1b42e9be78fd9e MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: src/osx/carbon/metafile.cpp
  3. // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional.
  4. // Author: Stefan Csomor
  5. // Modified by:
  6. // Created: 04/01/98
  7. // RCS-ID: $Id$
  8. // Copyright: (c) Stefan Csomor
  9. // Licence: wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Currently, the only purpose for making a metafile
  13. // is to put it on the clipboard.
  14. #include "wx/wxprec.h"
  15. #if wxUSE_METAFILE
  16. #ifndef WX_PRECOMP
  17. #include "wx/utils.h"
  18. #include "wx/app.h"
  19. #endif
  20. #include "wx/metafile.h"
  21. #include "wx/clipbrd.h"
  22. #include "wx/osx/private.h"
  23. #include "wx/graphics.h"
  24. #include "wx/osx/metafile.h"
  25. #include <stdio.h>
  26. #include <string.h>
  27. IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject)
  28. IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
  29. IMPLEMENT_ABSTRACT_CLASS(wxMetafileDCImpl, wxGCDCImpl)
  30. #define M_METAFILEREFDATA( a ) ((wxMetafileRefData*)(a).GetRefData())
  31. class wxMetafileRefData : public wxGDIRefData
  32. {
  33. public:
  34. // default ctor needed for CreateGDIRefData(), must be initialized later
  35. wxMetafileRefData() { Init(); }
  36. // creates a metafile from memory, assumes ownership
  37. wxMetafileRefData(CFDataRef data);
  38. // prepares a recording metafile
  39. wxMetafileRefData( int width, int height);
  40. // prepares a metafile to be read from a file (if filename is not empty)
  41. wxMetafileRefData( const wxString& filename);
  42. virtual ~wxMetafileRefData();
  43. virtual bool IsOk() const { return m_data != NULL; }
  44. void Init();
  45. int GetWidth() const { return m_width; }
  46. int GetHeight() const { return m_height; }
  47. CGPDFDocumentRef GetPDFDocument() const { return m_pdfDoc; }
  48. void UpdateDocumentFromData() ;
  49. const wxCFDataRef& GetData() const { return m_data; }
  50. CGContextRef GetContext() const { return m_context; }
  51. // ends the recording
  52. void Close();
  53. private:
  54. wxCFDataRef m_data;
  55. wxCFRef<CGPDFDocumentRef> m_pdfDoc;
  56. CGContextRef m_context;
  57. int m_width ;
  58. int m_height ;
  59. };
  60. wxMetafileRefData::wxMetafileRefData(CFDataRef data) :
  61. m_data(data)
  62. {
  63. Init();
  64. UpdateDocumentFromData();
  65. }
  66. wxMetafileRefData::wxMetafileRefData( const wxString& filename )
  67. {
  68. Init();
  69. if ( !filename.empty() )
  70. {
  71. wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(filename)));
  72. CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
  73. wxCFRef<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
  74. m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url));
  75. }
  76. }
  77. wxMetafileRefData::wxMetafileRefData( int width, int height)
  78. {
  79. Init();
  80. m_width = width;
  81. m_height = height;
  82. CGRect r = CGRectMake( 0 , 0 , width , height );
  83. CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
  84. m_data.reset(data);
  85. CGDataConsumerRef dataConsumer = wxMacCGDataConsumerCreateWithCFData(data);
  86. m_context = CGPDFContextCreate( dataConsumer, (width != 0 && height != 0) ? &r : NULL , NULL );
  87. CGDataConsumerRelease( dataConsumer );
  88. if ( m_context )
  89. {
  90. CGPDFContextBeginPage(m_context, NULL);
  91. CGColorSpaceRef genericColorSpace = wxMacGetGenericRGBColorSpace();
  92. CGContextSetFillColorSpace( m_context, genericColorSpace );
  93. CGContextSetStrokeColorSpace( m_context, genericColorSpace );
  94. CGContextTranslateCTM( m_context , 0 , height ) ;
  95. CGContextScaleCTM( m_context , 1 , -1 ) ;
  96. }
  97. }
  98. wxMetafileRefData::~wxMetafileRefData()
  99. {
  100. }
  101. void wxMetafileRefData::Init()
  102. {
  103. m_context = NULL;
  104. m_width = -1;
  105. m_height = -1;
  106. }
  107. void wxMetafileRefData::Close()
  108. {
  109. CGPDFContextEndPage(m_context);
  110. CGContextRelease(m_context);
  111. m_context = NULL;
  112. UpdateDocumentFromData();
  113. }
  114. void wxMetafileRefData::UpdateDocumentFromData()
  115. {
  116. wxCFRef<CGDataProviderRef> provider(wxMacCGDataProviderCreateWithCFData(m_data));
  117. m_pdfDoc.reset(CGPDFDocumentCreateWithProvider(provider));
  118. if ( m_pdfDoc != NULL )
  119. {
  120. CGPDFPageRef page = CGPDFDocumentGetPage( m_pdfDoc, 1 );
  121. CGRect rect = CGPDFPageGetBoxRect ( page, kCGPDFMediaBox);
  122. m_width = static_cast<int>(rect.size.width);
  123. m_height = static_cast<int>(rect.size.height);
  124. }
  125. }
  126. wxMetaFile::wxMetaFile(const wxString& file)
  127. {
  128. m_refData = new wxMetafileRefData(file);
  129. }
  130. wxMetaFile::~wxMetaFile()
  131. {
  132. }
  133. wxGDIRefData *wxMetaFile::CreateGDIRefData() const
  134. {
  135. return new wxMetafileRefData;
  136. }
  137. wxGDIRefData *wxMetaFile::CloneGDIRefData(const wxGDIRefData *data) const
  138. {
  139. return new wxMetafileRefData(*static_cast<const wxMetafileRefData *>(data));
  140. }
  141. WXHMETAFILE wxMetaFile::GetHMETAFILE() const
  142. {
  143. return (WXHMETAFILE) (CFDataRef) M_METAFILEDATA->GetData();
  144. }
  145. bool wxMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height))
  146. {
  147. bool success = true;
  148. #if wxUSE_DRAG_AND_DROP
  149. if (m_refData == NULL)
  150. return false;
  151. bool alreadyOpen = wxTheClipboard->IsOpened();
  152. if (!alreadyOpen)
  153. {
  154. wxTheClipboard->Open();
  155. wxTheClipboard->Clear();
  156. }
  157. wxDataObject *data = new wxMetafileDataObject( *this );
  158. success = wxTheClipboard->SetData( data );
  159. if (!alreadyOpen)
  160. wxTheClipboard->Close();
  161. #endif
  162. return success;
  163. }
  164. void wxMetafile::SetHMETAFILE(WXHMETAFILE mf)
  165. {
  166. UnRef();
  167. m_refData = new wxMetafileRefData((CFDataRef)mf);
  168. }
  169. #if wxOSX_USE_COCOA_OR_CARBON && !defined( __LP64__ )
  170. void wxMetafile::SetPICT(void* pictHandle)
  171. {
  172. UnRef();
  173. Handle picHandle = (Handle) pictHandle;
  174. HLock(picHandle);
  175. CFDataRef data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) *picHandle, GetHandleSize(picHandle), kCFAllocatorNull);
  176. wxCFRef<CGDataProviderRef> provider(wxMacCGDataProviderCreateWithCFData(data));
  177. QDPictRef pictRef = QDPictCreateWithProvider(provider);
  178. CGRect rect = QDPictGetBounds(pictRef);
  179. m_refData = new wxMetafileRefData(static_cast<int>(rect.size.width),
  180. static_cast<int>(rect.size.height));
  181. QDPictDrawToCGContext( ((wxMetafileRefData*) m_refData)->GetContext(), rect, pictRef );
  182. CFRelease( data );
  183. QDPictRelease( pictRef );
  184. ((wxMetafileRefData*) m_refData)->Close();
  185. }
  186. #endif
  187. bool wxMetaFile::Play(wxDC *dc)
  188. {
  189. if (!m_refData)
  190. return false;
  191. if (!dc->IsOk())
  192. return false;
  193. {
  194. wxDCImpl *impl = dc->GetImpl();
  195. wxGCDCImpl *gc_impl = wxDynamicCast(impl, wxGCDCImpl);
  196. if (gc_impl)
  197. {
  198. CGContextRef cg = (CGContextRef) (gc_impl->GetGraphicsContext()->GetNativeContext());
  199. CGPDFDocumentRef doc = M_METAFILEDATA->GetPDFDocument();
  200. CGPDFPageRef page = CGPDFDocumentGetPage( doc, 1 );
  201. wxMacCGContextStateSaver save(cg);
  202. CGContextDrawPDFPage( cg, page );
  203. }
  204. // CGContextTranslateCTM( cg, 0, bounds.size.width );
  205. // CGContextScaleCTM( cg, 1, -1 );
  206. }
  207. return true;
  208. }
  209. wxSize wxMetaFile::GetSize() const
  210. {
  211. wxSize dataSize = wxDefaultSize;
  212. if (Ok())
  213. {
  214. dataSize.x = M_METAFILEDATA->GetWidth();
  215. dataSize.y = M_METAFILEDATA->GetHeight();
  216. }
  217. return dataSize;
  218. }
  219. // Metafile device context
  220. // New constructor that takes origin and extent. If you use this, don't
  221. // give origin/extent arguments to wxMakeMetaFilePlaceable.
  222. wxMetafileDCImpl::wxMetafileDCImpl(
  223. wxDC *owner,
  224. const wxString& filename,
  225. int width, int height,
  226. const wxString& WXUNUSED(description) ) :
  227. wxGCDCImpl( owner )
  228. {
  229. wxASSERT_MSG( width != 0 || height != 0, wxT("no arbitration of metafile size supported") );
  230. wxASSERT_MSG( filename.empty(), wxT("no file based metafile support yet"));
  231. m_metaFile = new wxMetaFile( filename );
  232. wxMetafileRefData* metafiledata = new wxMetafileRefData(width, height);
  233. m_metaFile->UnRef();
  234. m_metaFile->SetRefData( metafiledata );
  235. SetGraphicsContext( wxGraphicsContext::CreateFromNative(metafiledata->GetContext()));
  236. m_ok = (m_graphicContext != NULL) ;
  237. SetMapMode( wxMM_TEXT );
  238. }
  239. wxMetafileDCImpl::~wxMetafileDCImpl()
  240. {
  241. }
  242. void wxMetafileDCImpl::DoGetSize(int *width, int *height) const
  243. {
  244. wxCHECK_RET( m_metaFile, wxT("GetSize() doesn't work without a metafile") );
  245. wxSize sz = m_metaFile->GetSize();
  246. if (width)
  247. (*width) = sz.x;
  248. if (height)
  249. (*height) = sz.y;
  250. }
  251. wxMetaFile *wxMetafileDCImpl::Close()
  252. {
  253. wxDELETE(m_graphicContext);
  254. m_ok = false;
  255. M_METAFILEREFDATA(*m_metaFile)->Close();
  256. return m_metaFile;
  257. }
  258. #if wxUSE_DATAOBJ
  259. size_t wxMetafileDataObject::GetDataSize() const
  260. {
  261. CFIndex length = 0;
  262. wxMetafileRefData* refData = M_METAFILEREFDATA(m_metafile);
  263. if ( refData )
  264. length = refData->GetData().GetLength();
  265. return length;
  266. }
  267. bool wxMetafileDataObject::GetDataHere(void *buf) const
  268. {
  269. bool result = false;
  270. wxMetafileRefData* refData = M_METAFILEREFDATA(m_metafile);
  271. if ( refData )
  272. {
  273. CFIndex length = refData->GetData().GetLength();
  274. if ( length > 0 )
  275. {
  276. result = true ;
  277. refData->GetData().GetBytes(CFRangeMake(0,length), (UInt8 *) buf);
  278. }
  279. }
  280. return result;
  281. }
  282. bool wxMetafileDataObject::SetData(size_t len, const void *buf)
  283. {
  284. wxMetafileRefData* metafiledata = new wxMetafileRefData(wxCFRefFromGet(wxCFDataRef((UInt8*)buf, len).get()));
  285. m_metafile.UnRef();
  286. m_metafile.SetRefData( metafiledata );
  287. return true;
  288. }
  289. #endif
  290. #endif