]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/metafile.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/metafile.cpp
3 // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional.
4 // Author: David Webster
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
21 #include "wx/metafile.h"
22 #include "wx/clipbrd.h"
23 #include "wx/os2/private.h"
28 extern bool wxClipboardIsOpen
;
30 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
)
31 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
)
35 * Currently, the only purpose for making a metafile is to put
36 * it on the clipboard.
39 wxMetafileRefData::wxMetafileRefData(void)
42 m_windowsMappingMode
= MM_ANISOTROPIC
;
45 wxMetafileRefData::~wxMetafileRefData(void)
49 // TODO: DeleteMetaFile((HMETAFILE) m_metafile);
54 wxMetafile::wxMetafile(const wxString
& file
)
56 m_refData
= new wxMetafileRefData
;
58 M_METAFILEDATA
->m_windowsMappingMode
= MM_ANISOTROPIC
;
59 M_METAFILEDATA
->m_metafile
= 0;
61 M_METAFILEDATA
->m_metafile
= (WXHANDLE
)0; // TODO: GetMetaFile(file);
64 wxMetafile::~wxMetafile(void)
68 wxGDIRefData
*wxMetafile::CreateGDIRefData() const
70 return new wxMetafileRefData
;
73 wxGDIRefData
*wxMetafile::CloneGDIRefData(const wxGDIRefData
*data
) const
75 return new wxMetafileRefData(*static_cast<const wxMetafileRefData
*>(data
));
78 bool wxMetafile::SetClipboard(int width
, int height
)
88 bool alreadyOpen
=wxClipboardOpen();
92 if (!wxEmptyClipboard()) return false;
94 bool success
= wxSetClipboardData(wxDF_METAFILE
, this, width
,height
);
95 if (!alreadyOpen
) wxCloseClipboard();
96 return (bool) success
;
100 bool wxMetafile::Play(wxDC
*dc
)
105 // if (dc->GetHDC() && M_METAFILEDATA->m_metafile)
106 // PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile);
111 void wxMetafile::SetHMETAFILE(WXHANDLE mf
)
114 m_refData
= new wxMetafileRefData
;
116 M_METAFILEDATA
->m_metafile
= mf
;
119 void wxMetafile::SetWindowsMappingMode(int mm
)
122 m_refData
= new wxMetafileRefData
;
124 M_METAFILEDATA
->m_windowsMappingMode
= mm
;
128 * Metafile device context
132 // Original constructor that does not takes origin and extent. If you use this,
133 // *DO* give origin/extent arguments to wxMakeMetafilePlaceable.
134 wxMetafileDCImpl::wxMetafileDCImpl(wxDC
*owner
, const wxString
& file
)
144 if ( wxFileExists(file
) )
150 m_hDC = (WXHDC) CreateMetaFile(file);
152 m_hDC = (WXHDC) CreateMetaFile(NULL);
155 m_ok
= (m_hDC
!= (WXHDC
) 0) ;
157 // Actual Windows mapping mode, for future reference.
158 m_windowsMappingMode
= wxMM_TEXT
;
160 SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
163 // New constructor that takes origin and extent. If you use this, don't
164 // give origin/extent arguments to wxMakeMetafilePlaceable.
165 wxMetafileDCImpl::wxMetafileDCImpl( wxDC
*owner
, const wxString
& file
,
176 if (!file
.empty() && wxFileExists(file
))
179 // m_hDC = (WXHDC) CreateMetaFile(file);
183 // ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL);
184 // ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL);
186 // Actual Windows mapping mode, for future reference.
187 m_windowsMappingMode
= MM_ANISOTROPIC
;
189 SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
192 wxMetafileDCImpl::~wxMetafileDCImpl(void)
197 void wxMetafileDCImpl::DoGetTextExtent(const wxString
& WXUNUSED(string
),
198 wxCoord
*WXUNUSED(x
),
199 wxCoord
*WXUNUSED(y
),
200 wxCoord
*WXUNUSED(descent
),
201 wxCoord
*WXUNUSED(externalLeading
),
202 const wxFont
*theFont
) const
204 const wxFont
*fontToUse
= theFont
;
210 HDC dc = GetDC(NULL);
214 GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect);
215 GetTextMetrics(dc, &tm);
224 *descent = tm.tmDescent;
225 if ( externalLeading )
226 *externalLeading = tm.tmExternalLeading;
230 wxMetafile
*wxMetafileDCImpl::Close(void)
232 SelectOldObjects(m_hDC
);
233 HANDLE mf
= 0; // TODO: CloseMetaFile((HDC) m_hDC);
237 wxMetafile
*wx_mf
= new wxMetafile
;
238 wx_mf
->SetHMETAFILE((WXHANDLE
) mf
);
239 wx_mf
->SetWindowsMappingMode(m_windowsMappingMode
);
245 void wxMetafileDCImpl::SetMapMode(wxMappingMode mode
)
247 m_mappingMode
= mode
;
249 // int pixel_width = 0;
250 // int pixel_height = 0;
252 // int mm_height = 0;
254 float mm2pixelsX
= 10.0;
255 float mm2pixelsY
= 10.0;
261 m_logicalScaleX
= (float)(twips2mm
* mm2pixelsX
);
262 m_logicalScaleY
= (float)(twips2mm
* mm2pixelsY
);
267 m_logicalScaleX
= (float)(pt2mm
* mm2pixelsX
);
268 m_logicalScaleY
= (float)(pt2mm
* mm2pixelsY
);
273 m_logicalScaleX
= mm2pixelsX
;
274 m_logicalScaleY
= mm2pixelsY
;
279 m_logicalScaleX
= (float)(mm2pixelsX
/10.0);
280 m_logicalScaleY
= (float)(mm2pixelsY
/10.0);
286 m_logicalScaleX
= 1.0;
287 m_logicalScaleY
= 1.0;
304 struct mfPLACEABLEHEADER
{
313 struct mfPLACEABLEHEADER
{
324 * Pass filename of existing non-placeable metafile, and bounding box.
325 * Adds a placeable metafile header, sets the mapping mode to anisotropic,
326 * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode.
330 bool wxMakeMetafilePlaceable(const wxString
& filename
, float scale
)
332 return wxMakeMetafilePlaceable(filename
, 0, 0, 0, 0, scale
, FALSE
);
335 bool wxMakeMetafilePlaceable(const wxString
& WXUNUSED(filename
),
340 float WXUNUSED(scale
),
341 bool WXUNUSED(useOriginAndExtent
))
343 // TODO: the OS/2 PM/MM way to do this
345 // I'm not sure if this is the correct way of suggesting a scale
346 // to the client application, but it's the only way I can find.
347 int unitsPerInch = (int)(576/scale);
349 mfPLACEABLEHEADER header;
350 header.key = 0x9AC6CDD7L;
352 header.bbox.xLeft = (int)(x1);
353 header.bbox.yTop = (int)(y1);
354 header.bbox.xRight = (int)(x2);
355 header.bbox.yBottom = (int)(y2);
356 header.inch = unitsPerInch;
359 // Calculate checksum
361 mfPLACEABLEHEADER *pMFHead = &header;
362 for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; p < (WORD *)&pMFHead ->checksum; ++p)
363 pMFHead ->checksum ^= *p;
365 FILE *fd = fopen(filename.fn_str(), "rb");
369 wxChar tempFileBuf[256];
370 wxGetTempFileName(wxT("mf"), tempFileBuf);
371 FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb");
374 fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle);
376 // Calculate origin and extent
379 int extentX = x2 - x1;
380 int extentY = (y2 - y1);
382 // Read metafile header and write
383 METAHEADER metaHeader;
384 fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd);
386 if (useOriginAndExtent)
387 metaHeader.mtSize += 15;
389 metaHeader.mtSize += 5;
391 fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle);
393 // Write SetMapMode, SetWindowOrigin and SetWindowExt records
395 char originBuffer[10];
396 char extentBuffer[10];
397 METARECORD *modeRecord = (METARECORD *)&modeBuffer;
399 METARECORD *originRecord = (METARECORD *)&originBuffer;
400 METARECORD *extentRecord = (METARECORD *)&extentBuffer;
402 modeRecord->rdSize = 4;
403 modeRecord->rdFunction = META_SETMAPMODE;
404 modeRecord->rdParm[0] = MM_ANISOTROPIC;
406 originRecord->rdSize = 5;
407 originRecord->rdFunction = META_SETWINDOWORG;
408 originRecord->rdParm[0] = originY;
409 originRecord->rdParm[1] = originX;
411 extentRecord->rdSize = 5;
412 extentRecord->rdFunction = META_SETWINDOWEXT;
413 extentRecord->rdParm[0] = extentY;
414 extentRecord->rdParm[1] = extentX;
416 fwrite((void *)modeBuffer, sizeof(char), 8, fHandle);
418 if (useOriginAndExtent)
420 fwrite((void *)originBuffer, sizeof(char), 10, fHandle);
421 fwrite((void *)extentBuffer, sizeof(char), 10, fHandle);
435 wxRemoveFile(filename);
436 wxCopyFile(tempFileBuf, filename);
437 wxRemoveFile(tempFileBuf);
442 #endif // wxUSE_METAFILE