X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/265b0c070b7531a31d79e79fd44142f5a807b23d..d485bda109d5ef0fef36a3f737549e9b9f54baab:/src/msw/metafile.cpp diff --git a/src/msw/metafile.cpp b/src/msw/metafile.cpp index a49e59a0ba..3cbb79fb63 100644 --- a/src/msw/metafile.cpp +++ b/src/msw/metafile.cpp @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: msw/metafile.cpp +// Name: src/msw/metafile.cpp // Purpose: wxMetafileDC etc. // Author: Julian Smart // Modified by: VZ 07.01.00: implemented wxMetaFileDataObject // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -17,10 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "metafile.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -28,18 +24,16 @@ #pragma hdrstop #endif -#ifndef WX_PRECOMP - #include "wx/setup.h" -#endif - -#if wxUSE_METAFILE - #ifndef WX_PRECOMP #include "wx/utils.h" #include "wx/app.h" #endif #include "wx/metafile.h" +#include "wx/filename.h" + +#if wxUSE_METAFILE && !defined(wxMETAFILE_IS_ENH) + #include "wx/clipbrd.h" #include "wx/msw/private.h" @@ -70,7 +64,7 @@ IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC) wxMetafileRefData::wxMetafileRefData() { m_metafile = 0; - m_windowsMappingMode = wxMM_ANISOTROPIC; + m_windowsMappingMode = MM_ANISOTROPIC; m_width = m_height = 0; } @@ -91,9 +85,9 @@ wxMetafile::wxMetafile(const wxString& file) { m_refData = new wxMetafileRefData; - M_METAFILEDATA->m_windowsMappingMode = wxMM_ANISOTROPIC; + M_METAFILEDATA->m_windowsMappingMode = MM_ANISOTROPIC; M_METAFILEDATA->m_metafile = 0; - if (!file.IsNull() && (file.Cmp(wxT("")) == 0)) + if (!file.empty()) M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile(file); } @@ -101,38 +95,54 @@ wxMetafile::~wxMetafile() { } +wxGDIRefData *wxMetafile::CreateGDIRefData() const +{ + return new wxMetafileRefData; +} + +wxGDIRefData *wxMetafile::CloneGDIRefData(const wxGDIRefData *data) const +{ + return new wxMetafileRefData(*static_cast(data)); +} + bool wxMetafile::SetClipboard(int width, int height) { +#if !wxUSE_CLIPBOARD + return false; +#else if (!m_refData) - return FALSE; + return false; bool alreadyOpen = wxClipboardOpen(); if (!alreadyOpen) { wxOpenClipboard(); if (!wxEmptyClipboard()) - return FALSE; + return false; } bool success = wxSetClipboardData(wxDF_METAFILE, this, width,height); if (!alreadyOpen) wxCloseClipboard(); return success; +#endif } bool wxMetafile::Play(wxDC *dc) { if (!m_refData) - return FALSE; - - dc->BeginDrawing(); + return false; if (dc->GetHDC() && M_METAFILEDATA->m_metafile) - PlayMetaFile(GetHdcOf(*dc), (HMETAFILE) M_METAFILEDATA->m_metafile); - - dc->EndDrawing(); + { + if ( !::PlayMetaFile(GetHdcOf(*dc), (HMETAFILE) + M_METAFILEDATA->m_metafile) ) + { + wxLogLastError(wxT("PlayMetaFile")); + } + } - return TRUE; + return true; } void wxMetafile::SetHMETAFILE(WXHANDLE mf) @@ -157,7 +167,8 @@ void wxMetafile::SetWindowsMappingMode(int mm) // 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) +wxMetafileDCImpl::wxMetafileDCImpl(wxDC *owner, const wxString& file) + : wxMSWDCImpl(owner) { m_metaFile = NULL; m_minX = 10000; @@ -166,13 +177,13 @@ wxMetafileDC::wxMetafileDC(const wxString& file) m_maxY = -10000; // m_title = NULL; - if (!file.IsNull() && wxFileExists(file)) + if ( wxFileExists(file) ) wxRemoveFile(file); - if (!file.IsNull() && (file != wxT(""))) - m_hDC = (WXHDC) CreateMetaFile(file); - else + if ( file.empty() ) m_hDC = (WXHDC) CreateMetaFile(NULL); + else + m_hDC = (WXHDC) CreateMetaFile(file); m_ok = (m_hDC != (WXHDC) 0) ; @@ -184,47 +195,50 @@ wxMetafileDC::wxMetafileDC(const wxString& file) // 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) +wxMetafileDCImpl::wxMetafileDCImpl(wxDC *owner, const wxString& file, + int xext, int yext, int xorg, int yorg) + : wxMSWDCImpl(owner) { m_minX = 10000; m_minY = 10000; m_maxX = -10000; m_maxY = -10000; - if ( !!file && wxFileExists(file)) + if ( !file.empty() && wxFileExists(file) ) wxRemoveFile(file); - m_hDC = (WXHDC) CreateMetaFile(file); + m_hDC = (WXHDC) CreateMetaFile(file.empty() ? NULL : wxMSW_CONV_LPCTSTR(file)); - m_ok = TRUE; + m_ok = true; ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL); ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL); // Actual Windows mapping mode, for future reference. - m_windowsMappingMode = wxMM_ANISOTROPIC; + m_windowsMappingMode = MM_ANISOTROPIC; SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct) } -wxMetafileDC::~wxMetafileDC() +wxMetafileDCImpl::~wxMetafileDCImpl() { m_hDC = 0; } -void wxMetafileDC::GetTextExtent(const wxString& string, long *x, long *y, - long *descent, long *externalLeading, wxFont *theFont, bool use16bit) const +void wxMetafileDCImpl::DoGetTextExtent(const wxString& string, + wxCoord *x, wxCoord *y, + wxCoord *descent, wxCoord *externalLeading, + const wxFont *theFont) const { - wxFont *fontToUse = theFont; + const wxFont *fontToUse = theFont; if (!fontToUse) - fontToUse = (wxFont*) &m_font; + fontToUse = &m_font; - HDC dc = GetDC(NULL); + ScreenHDC dc; + SelectInHDC selFont(dc, GetHfontOf(*fontToUse)); SIZE sizeRect; TEXTMETRIC tm; - GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); - GetTextMetrics(dc, &tm); - - ReleaseDC(NULL, dc); + ::GetTextExtentPoint32(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); + ::GetTextMetrics(dc, &tm); if ( x ) *x = sizeRect.cx; @@ -236,7 +250,17 @@ void wxMetafileDC::GetTextExtent(const wxString& string, long *x, long *y, *externalLeading = tm.tmExternalLeading; } -wxMetafile *wxMetafileDC::Close() +void wxMetafileDCImpl::DoGetSize(int *width, int *height) const +{ + wxCHECK_RET( m_refData, wxT("invalid wxMetafileDC") ); + + if ( width ) + *width = M_METAFILEDATA->m_width; + if ( height ) + *height = M_METAFILEDATA->m_height; +} + +wxMetafile *wxMetafileDCImpl::Close() { SelectOldObjects(m_hDC); HANDLE mf = CloseMetaFile((HDC) m_hDC); @@ -251,7 +275,7 @@ wxMetafile *wxMetafileDC::Close() return NULL; } -void wxMetafileDC::SetMapMode(int mode) +void wxMetafileDCImpl::SetMapMode(wxMappingMode mode) { m_mappingMode = mode; @@ -297,8 +321,6 @@ void wxMetafileDC::SetMapMode(int mode) break; } } - m_windowExtX = 100; - m_windowExtY = 100; } // ---------------------------------------------------------------------------- @@ -342,7 +364,7 @@ struct mfPLACEABLEHEADER { bool wxMakeMetafilePlaceable(const wxString& filename, float scale) { - return wxMakeMetafilePlaceable(filename, 0, 0, 0, 0, scale, FALSE); + 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) @@ -368,15 +390,17 @@ bool wxMakeMetafilePlaceable(const wxString& filename, int x1, int y1, int x2, i p < (WORD *)&pMFHead ->checksum; ++p) pMFHead ->checksum ^= *p; - FILE *fd = fopen(filename.fn_str(), "rb"); - if (!fd) return FALSE; + FILE *fd = wxFopen(filename.fn_str(), wxT("rb")); + if (!fd) return false; - wxChar tempFileBuf[256]; - wxGetTempFileName(wxT("mf"), tempFileBuf); - FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb"); + wxString tempFileBuf = wxFileName::CreateTempFileName(wxT("mf")); + if (tempFileBuf.empty()) + return false; + + FILE *fHandle = wxFopen(tempFileBuf.fn_str(), wxT("wb")); if (!fHandle) - return FALSE; - fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle); + return false; + fwrite((void *)&header, 1, sizeof(mfPLACEABLEHEADER), fHandle); // Calculate origin and extent int originX = x1; @@ -386,14 +410,14 @@ bool wxMakeMetafilePlaceable(const wxString& filename, int x1, int y1, int x2, i // Read metafile header and write METAHEADER metaHeader; - fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd); + fread((void *)&metaHeader, 1, sizeof(metaHeader), fd); if (useOriginAndExtent) metaHeader.mtSize += 15; else metaHeader.mtSize += 5; - fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle); + fwrite((void *)&metaHeader, 1, sizeof(metaHeader), fHandle); // Write SetMapMode, SetWindowOrigin and SetWindowExt records char modeBuffer[8]; @@ -418,12 +442,12 @@ bool wxMakeMetafilePlaceable(const wxString& filename, int x1, int y1, int x2, i extentRecord->rdParm[0] = extentY; extentRecord->rdParm[1] = extentX; - fwrite((void *)modeBuffer, sizeof(char), 8, fHandle); + fwrite((void *)modeBuffer, 1, 8, fHandle); if (useOriginAndExtent) { - fwrite((void *)originBuffer, sizeof(char), 10, fHandle); - fwrite((void *)extentBuffer, sizeof(char), 10, fHandle); + fwrite((void *)originBuffer, 1, 10, fHandle); + fwrite((void *)extentBuffer, 1, 10, fHandle); } int ch = -2; @@ -440,9 +464,12 @@ bool wxMakeMetafilePlaceable(const wxString& filename, int x1, int y1, int x2, i wxRemoveFile(filename); wxCopyFile(tempFileBuf, filename); wxRemoveFile(tempFileBuf); - return TRUE; + return true; } + +#if wxUSE_DRAG_AND_DROP + // ---------------------------------------------------------------------------- // wxMetafileDataObject // ---------------------------------------------------------------------------- @@ -455,15 +482,22 @@ size_t wxMetafileDataObject::GetDataSize() const bool wxMetafileDataObject::GetDataHere(void *buf) const { METAFILEPICT *mfpict = (METAFILEPICT *)buf; - const wxMetafile mf = GetMetafile(); - mfpict->mm = mf.GetWindowsMappingMode(); + const wxMetafile& mf = GetMetafile(); + + wxCHECK_MSG( mf.GetHMETAFILE(), false, wxT("copying invalid metafile") ); + + // doesn't seem to work with any other mapping mode... + mfpict->mm = MM_ANISOTROPIC; //mf.GetWindowsMappingMode(); mfpict->xExt = mf.GetWidth(); mfpict->yExt = mf.GetHeight(); - mfpict->hMF = (HMETAFILE)mf.GetHMETAFILE(); - wxCHECK_MSG( mfpict->hMF, FALSE, _T("copying invalid metafile") ); + // transform the picture size to HIMETRIC units (0.01mm) - as we don't know + // what DC the picture will be rendered to, use the default display one + PixelToHIMETRIC(&mfpict->xExt, &mfpict->yExt); - return TRUE; + mfpict->hMF = CopyMetaFile((HMETAFILE)mf.GetHMETAFILE(), NULL); + + return true; } bool wxMetafileDataObject::SetData(size_t WXUNUSED(len), const void *buf) @@ -472,16 +506,27 @@ bool wxMetafileDataObject::SetData(size_t WXUNUSED(len), const void *buf) wxMetafile mf; mf.SetWindowsMappingMode(mfpict->mm); - mf.SetWidth(mfpict->xExt); - mf.SetHeight(mfpict->yExt); + + LONG w = mfpict->xExt, + h = mfpict->yExt; + if ( mfpict->mm == MM_ANISOTROPIC ) + { + // in this case xExt and yExt contain suggested size in HIMETRIC units + // (0.01 mm) - transform this to something more reasonable (pixels) + HIMETRICToPixel(&w, &h); + } + + mf.SetWidth(w); + mf.SetHeight(h); mf.SetHMETAFILE((WXHANDLE)mfpict->hMF); - wxCHECK_MSG( mfpict->hMF, FALSE, _T("pasting invalid metafile") ); + wxCHECK_MSG( mfpict->hMF, false, wxT("pasting invalid metafile") ); SetMetafile(mf); - return TRUE; + return true; } -#endif // wxUSE_METAFILE +#endif // wxUSE_DRAG_AND_DROP +#endif // wxUSE_METAFILE