]>
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
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
22 #include "wx/metafile.h"
23 #include "wx/clipbrd.h"
24 #include "wx/os2/private.h"
29 extern bool wxClipboardIsOpen
;
31 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
)
32 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
)
36 * Currently, the only purpose for making a metafile is to put
37 * it on the clipboard.
40 wxMetafileRefData::wxMetafileRefData(void)
43 m_windowsMappingMode
= wxMM_ANISOTROPIC
;
46 wxMetafileRefData::~wxMetafileRefData(void)
50 // TODO: DeleteMetaFile((HMETAFILE) m_metafile);
55 wxMetafile::wxMetafile(const wxString
& file
)
57 m_refData
= new wxMetafileRefData
;
59 M_METAFILEDATA
->m_windowsMappingMode
= wxMM_ANISOTROPIC
;
60 M_METAFILEDATA
->m_metafile
= 0;
62 M_METAFILEDATA
->m_metafile
= (WXHANDLE
)0; // TODO: GetMetaFile(file);
65 wxMetafile::~wxMetafile(void)
69 bool wxMetafile::SetClipboard(int width
, int height
)
79 bool alreadyOpen
=wxClipboardOpen();
83 if (!wxEmptyClipboard()) return false;
85 bool success
= wxSetClipboardData(wxDF_METAFILE
, this, width
,height
);
86 if (!alreadyOpen
) wxCloseClipboard();
87 return (bool) success
;
91 bool wxMetafile::Play(wxDC
*dc
)
96 // if (dc->GetHDC() && M_METAFILEDATA->m_metafile)
97 // PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile);
102 void wxMetafile::SetHMETAFILE(WXHANDLE mf
)
105 m_refData
= new wxMetafileRefData
;
107 M_METAFILEDATA
->m_metafile
= mf
;
110 void wxMetafile::SetWindowsMappingMode(int mm
)
113 m_refData
= new wxMetafileRefData
;
115 M_METAFILEDATA
->m_windowsMappingMode
= mm
;
119 * Metafile device context
123 // Original constructor that does not takes origin and extent. If you use this,
124 // *DO* give origin/extent arguments to wxMakeMetafilePlaceable.
125 wxMetafileDC::wxMetafileDC(const wxString
& file
)
134 if (!file
.IsNull() && wxFileExists(file
))
140 m_hDC = (WXHDC) CreateMetaFile(file);
142 m_hDC = (WXHDC) CreateMetaFile(NULL);
145 m_ok
= (m_hDC
!= (WXHDC
) 0) ;
147 // Actual Windows mapping mode, for future reference.
148 m_windowsMappingMode
= wxMM_TEXT
;
150 SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
153 // New constructor that takes origin and extent. If you use this, don't
154 // give origin/extent arguments to wxMakeMetafilePlaceable.
155 wxMetafileDC::wxMetafileDC( const wxString
& file
,
165 if (!file
.empty() && wxFileExists(file
))
168 // m_hDC = (WXHDC) CreateMetaFile(file);
172 // ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL);
173 // ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL);
175 // Actual Windows mapping mode, for future reference.
176 m_windowsMappingMode
= wxMM_ANISOTROPIC
;
178 SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
181 wxMetafileDC::~wxMetafileDC(void)
186 void wxMetafileDC::GetTextExtent(const wxString
& WXUNUSED(string
),
189 long *WXUNUSED(descent
),
190 long *WXUNUSED(externalLeading
),
191 const wxFont
*theFont
,
192 bool WXUNUSED(use16bit
) ) const
194 const wxFont
*fontToUse
= theFont
;
200 HDC dc = GetDC(NULL);
204 GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect);
205 GetTextMetrics(dc, &tm);
214 *descent = tm.tmDescent;
215 if ( externalLeading )
216 *externalLeading = tm.tmExternalLeading;
220 wxMetafile
*wxMetafileDC::Close(void)
222 SelectOldObjects(m_hDC
);
223 HANDLE mf
= 0; // TODO: CloseMetaFile((HDC) m_hDC);
227 wxMetafile
*wx_mf
= new wxMetafile
;
228 wx_mf
->SetHMETAFILE((WXHANDLE
) mf
);
229 wx_mf
->SetWindowsMappingMode(m_windowsMappingMode
);
235 void wxMetafileDC::SetMapMode(int mode
)
237 m_mappingMode
= mode
;
239 // int pixel_width = 0;
240 // int pixel_height = 0;
242 // int mm_height = 0;
244 float mm2pixelsX
= 10.0;
245 float mm2pixelsY
= 10.0;
251 m_logicalScaleX
= (float)(twips2mm
* mm2pixelsX
);
252 m_logicalScaleY
= (float)(twips2mm
* mm2pixelsY
);
257 m_logicalScaleX
= (float)(pt2mm
* mm2pixelsX
);
258 m_logicalScaleY
= (float)(pt2mm
* mm2pixelsY
);
263 m_logicalScaleX
= mm2pixelsX
;
264 m_logicalScaleY
= mm2pixelsY
;
269 m_logicalScaleX
= (float)(mm2pixelsX
/10.0);
270 m_logicalScaleY
= (float)(mm2pixelsY
/10.0);
276 m_logicalScaleX
= 1.0;
277 m_logicalScaleY
= 1.0;
294 struct mfPLACEABLEHEADER
{
303 struct mfPLACEABLEHEADER
{
314 * Pass filename of existing non-placeable metafile, and bounding box.
315 * Adds a placeable metafile header, sets the mapping mode to anisotropic,
316 * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode.
320 bool wxMakeMetafilePlaceable(const wxString
& filename
, float scale
)
322 return wxMakeMetafilePlaceable(filename
, 0, 0, 0, 0, scale
, FALSE
);
325 bool wxMakeMetafilePlaceable(const wxString
& WXUNUSED(filename
),
330 float WXUNUSED(scale
),
331 bool WXUNUSED(useOriginAndExtent
))
333 // TODO: the OS/2 PM/MM way to do this
335 // I'm not sure if this is the correct way of suggesting a scale
336 // to the client application, but it's the only way I can find.
337 int unitsPerInch = (int)(576/scale);
339 mfPLACEABLEHEADER header;
340 header.key = 0x9AC6CDD7L;
342 header.bbox.xLeft = (int)(x1);
343 header.bbox.yTop = (int)(y1);
344 header.bbox.xRight = (int)(x2);
345 header.bbox.yBottom = (int)(y2);
346 header.inch = unitsPerInch;
349 // Calculate checksum
351 mfPLACEABLEHEADER *pMFHead = &header;
352 for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; p < (WORD *)&pMFHead ->checksum; ++p)
353 pMFHead ->checksum ^= *p;
355 FILE *fd = fopen(filename.fn_str(), "rb");
359 wxChar tempFileBuf[256];
360 wxGetTempFileName(wxT("mf"), tempFileBuf);
361 FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb");
364 fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle);
366 // Calculate origin and extent
369 int extentX = x2 - x1;
370 int extentY = (y2 - y1);
372 // Read metafile header and write
373 METAHEADER metaHeader;
374 fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd);
376 if (useOriginAndExtent)
377 metaHeader.mtSize += 15;
379 metaHeader.mtSize += 5;
381 fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle);
383 // Write SetMapMode, SetWindowOrigin and SetWindowExt records
385 char originBuffer[10];
386 char extentBuffer[10];
387 METARECORD *modeRecord = (METARECORD *)&modeBuffer;
389 METARECORD *originRecord = (METARECORD *)&originBuffer;
390 METARECORD *extentRecord = (METARECORD *)&extentBuffer;
392 modeRecord->rdSize = 4;
393 modeRecord->rdFunction = META_SETMAPMODE;
394 modeRecord->rdParm[0] = MM_ANISOTROPIC;
396 originRecord->rdSize = 5;
397 originRecord->rdFunction = META_SETWINDOWORG;
398 originRecord->rdParm[0] = originY;
399 originRecord->rdParm[1] = originX;
401 extentRecord->rdSize = 5;
402 extentRecord->rdFunction = META_SETWINDOWEXT;
403 extentRecord->rdParm[0] = extentY;
404 extentRecord->rdParm[1] = extentX;
406 fwrite((void *)modeBuffer, sizeof(char), 8, fHandle);
408 if (useOriginAndExtent)
410 fwrite((void *)originBuffer, sizeof(char), 10, fHandle);
411 fwrite((void *)extentBuffer, sizeof(char), 10, fHandle);
425 wxRemoveFile(filename);
426 wxCopyFile(tempFileBuf, filename);
427 wxRemoveFile(tempFileBuf);
432 #endif // wxUSE_METAFILE