]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/metafile.cpp
1 /////////////////////////////////////////////////////////////////////////////
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"
26 #include "wx/metafile.h"
27 #include "wx/clipbrd.h"
28 #include "wx/os2/private.h"
33 extern bool wxClipboardIsOpen
;
35 IMPLEMENT_DYNAMIC_CLASS(wxMetafile
, wxObject
)
36 IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC
, wxDC
)
40 * Currently, the only purpose for making a metafile is to put
41 * it on the clipboard.
44 wxMetafileRefData::wxMetafileRefData(void)
47 m_windowsMappingMode
= wxMM_ANISOTROPIC
;
50 wxMetafileRefData::~wxMetafileRefData(void)
54 // TODO: DeleteMetaFile((HMETAFILE) m_metafile);
59 wxMetafile::wxMetafile(const wxString
& file
)
61 m_refData
= new wxMetafileRefData
;
63 M_METAFILEDATA
->m_windowsMappingMode
= wxMM_ANISOTROPIC
;
64 M_METAFILEDATA
->m_metafile
= 0;
65 if (!file
.IsNull() && (file
.Cmp(wxT("")) == 0))
66 M_METAFILEDATA
->m_metafile
= (WXHANDLE
)0; // TODO: GetMetaFile(file);
69 wxMetafile::~wxMetafile(void)
73 bool wxMetafile::SetClipboard(int width
, int height
)
78 bool alreadyOpen
=wxClipboardOpen();
82 if (!wxEmptyClipboard()) return FALSE
;
84 bool success
= wxSetClipboardData(wxDF_METAFILE
, this, width
,height
);
85 if (!alreadyOpen
) wxCloseClipboard();
86 return (bool) success
;
89 bool wxMetafile::Play(wxDC
*dc
)
96 // if (dc->GetHDC() && M_METAFILEDATA->m_metafile)
97 // PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile);
104 void wxMetafile::SetHMETAFILE(WXHANDLE mf
)
107 m_refData
= new wxMetafileRefData
;
109 M_METAFILEDATA
->m_metafile
= mf
;
112 void wxMetafile::SetWindowsMappingMode(int mm
)
115 m_refData
= new wxMetafileRefData
;
117 M_METAFILEDATA
->m_windowsMappingMode
= mm
;
121 * Metafile device context
125 // Original constructor that does not takes origin and extent. If you use this,
126 // *DO* give origin/extent arguments to wxMakeMetafilePlaceable.
127 wxMetafileDC::wxMetafileDC(const wxString
& file
)
136 if (!file
.IsNull() && wxFileExists(file
))
141 if (!file.IsNull() && (file != wxT("")))
142 m_hDC = (WXHDC) CreateMetaFile(file);
144 m_hDC = (WXHDC) CreateMetaFile(NULL);
147 m_ok
= (m_hDC
!= (WXHDC
) 0) ;
149 // Actual Windows mapping mode, for future reference.
150 m_windowsMappingMode
= wxMM_TEXT
;
152 SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
155 // New constructor that takes origin and extent. If you use this, don't
156 // give origin/extent arguments to wxMakeMetafilePlaceable.
157 wxMetafileDC::wxMetafileDC(const wxString
& file
, int xext
, int yext
, int xorg
, int yorg
)
163 if (file
!= wxT("") && wxFileExists(file
)) wxRemoveFile(file
);
164 // m_hDC = (WXHDC) CreateMetaFile(file);
168 // ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL);
169 // ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL);
171 // Actual Windows mapping mode, for future reference.
172 m_windowsMappingMode
= wxMM_ANISOTROPIC
;
174 SetMapMode(wxMM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
177 wxMetafileDC::~wxMetafileDC(void)
182 void wxMetafileDC::GetTextExtent(const wxString
& string
, long *x
, long *y
,
183 long *descent
, long *externalLeading
, wxFont
*theFont
, bool use16bit
) const
185 wxFont
*fontToUse
= theFont
;
187 fontToUse
= (wxFont
*) &m_font
;
191 HDC dc = GetDC(NULL);
195 GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect);
196 GetTextMetrics(dc, &tm);
205 *descent = tm.tmDescent;
206 if ( externalLeading )
207 *externalLeading = tm.tmExternalLeading;
211 wxMetafile
*wxMetafileDC::Close(void)
213 SelectOldObjects(m_hDC
);
214 HANDLE mf
= 0; // TODO: CloseMetaFile((HDC) m_hDC);
218 wxMetafile
*wx_mf
= new wxMetafile
;
219 wx_mf
->SetHMETAFILE((WXHANDLE
) mf
);
220 wx_mf
->SetWindowsMappingMode(m_windowsMappingMode
);
226 void wxMetafileDC::SetMapMode(int mode
)
228 m_mappingMode
= mode
;
230 // int pixel_width = 0;
231 // int pixel_height = 0;
233 // int mm_height = 0;
235 float mm2pixelsX
= 10.0;
236 float mm2pixelsY
= 10.0;
242 m_logicalScaleX
= (float)(twips2mm
* mm2pixelsX
);
243 m_logicalScaleY
= (float)(twips2mm
* mm2pixelsY
);
248 m_logicalScaleX
= (float)(pt2mm
* mm2pixelsX
);
249 m_logicalScaleY
= (float)(pt2mm
* mm2pixelsY
);
254 m_logicalScaleX
= mm2pixelsX
;
255 m_logicalScaleY
= mm2pixelsY
;
260 m_logicalScaleX
= (float)(mm2pixelsX
/10.0);
261 m_logicalScaleY
= (float)(mm2pixelsY
/10.0);
267 m_logicalScaleX
= 1.0;
268 m_logicalScaleY
= 1.0;
285 struct mfPLACEABLEHEADER
{
294 struct mfPLACEABLEHEADER
{
305 * Pass filename of existing non-placeable metafile, and bounding box.
306 * Adds a placeable metafile header, sets the mapping mode to anisotropic,
307 * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode.
311 bool wxMakeMetafilePlaceable(const wxString
& filename
, float scale
)
313 return wxMakeMetafilePlaceable(filename
, 0, 0, 0, 0, scale
, FALSE
);
316 bool wxMakeMetafilePlaceable(const wxString
& filename
, int x1
, int y1
, int x2
, int y2
, float scale
, bool useOriginAndExtent
)
318 // TODO: the OS/2 PM/MM way to do this
320 // I'm not sure if this is the correct way of suggesting a scale
321 // to the client application, but it's the only way I can find.
322 int unitsPerInch = (int)(576/scale);
324 mfPLACEABLEHEADER header;
325 header.key = 0x9AC6CDD7L;
327 header.bbox.xLeft = (int)(x1);
328 header.bbox.yTop = (int)(y1);
329 header.bbox.xRight = (int)(x2);
330 header.bbox.yBottom = (int)(y2);
331 header.inch = unitsPerInch;
334 // Calculate checksum
336 mfPLACEABLEHEADER *pMFHead = &header;
337 for (p =(WORD *)pMFHead,pMFHead -> checksum = 0;
338 p < (WORD *)&pMFHead ->checksum; ++p)
339 pMFHead ->checksum ^= *p;
341 FILE *fd = fopen(filename.fn_str(), "rb");
342 if (!fd) return FALSE;
344 wxChar tempFileBuf[256];
345 wxGetTempFileName(wxT("mf"), tempFileBuf);
346 FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb");
349 fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle);
351 // Calculate origin and extent
354 int extentX = x2 - x1;
355 int extentY = (y2 - y1);
357 // Read metafile header and write
358 METAHEADER metaHeader;
359 fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd);
361 if (useOriginAndExtent)
362 metaHeader.mtSize += 15;
364 metaHeader.mtSize += 5;
366 fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle);
368 // Write SetMapMode, SetWindowOrigin and SetWindowExt records
370 char originBuffer[10];
371 char extentBuffer[10];
372 METARECORD *modeRecord = (METARECORD *)&modeBuffer;
374 METARECORD *originRecord = (METARECORD *)&originBuffer;
375 METARECORD *extentRecord = (METARECORD *)&extentBuffer;
377 modeRecord->rdSize = 4;
378 modeRecord->rdFunction = META_SETMAPMODE;
379 modeRecord->rdParm[0] = MM_ANISOTROPIC;
381 originRecord->rdSize = 5;
382 originRecord->rdFunction = META_SETWINDOWORG;
383 originRecord->rdParm[0] = originY;
384 originRecord->rdParm[1] = originX;
386 extentRecord->rdSize = 5;
387 extentRecord->rdFunction = META_SETWINDOWEXT;
388 extentRecord->rdParm[0] = extentY;
389 extentRecord->rdParm[1] = extentX;
391 fwrite((void *)modeBuffer, sizeof(char), 8, fHandle);
393 if (useOriginAndExtent)
395 fwrite((void *)originBuffer, sizeof(char), 10, fHandle);
396 fwrite((void *)extentBuffer, sizeof(char), 10, fHandle);
410 wxRemoveFile(filename);
411 wxCopyFile(tempFileBuf, filename);
412 wxRemoveFile(tempFileBuf);
417 #endif // wxUSE_METAFILE