]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/metafile.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMetaFileDC etc.
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "metafile.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
34 #include "wx/metafile.h"
35 #include "wx/clipbrd.h"
36 #include "wx/msw/private.h"
41 extern bool wxClipboardIsOpen
;
43 #if !USE_SHARED_LIBRARY
44 IMPLEMENT_DYNAMIC_CLASS(wxMetaFile
, wxObject
)
45 IMPLEMENT_ABSTRACT_CLASS(wxMetaFileDC
, wxDC
)
49 * Metafiles - Windows 3.1 only
50 * Currently, the only purpose for making a metafile is to put
51 * it on the clipboard.
54 wxMetaFile::wxMetaFile(const wxString
& file
)
56 m_windowsMappingMode
= MM_ANISOTROPIC
;
58 if (!file
.IsNull() && file
== "")
59 m_metaFile
= (WXHANDLE
) GetMetaFile(file
);
62 wxMetaFile::~wxMetaFile(void)
65 { DeleteMetaFile((HANDLE
) m_metaFile
); m_metaFile
= 0; }
68 bool wxMetaFile::SetClipboard(int width
, int height
)
70 bool alreadyOpen
=wxClipboardOpen();
74 if (!wxEmptyClipboard()) return FALSE
;
76 bool success
= wxSetClipboardData(wxCF_METAFILE
,this, width
,height
);
77 if (!alreadyOpen
) wxCloseClipboard();
78 return (bool) success
;
81 bool wxMetaFile::Play(wxDC
*dc
)
85 if (dc
->GetHDC() && m_metaFile
)
86 PlayMetaFile((HDC
) dc
->GetHDC(), (HANDLE
) m_metaFile
);
94 * Metafile device context
98 // Original constructor that does not takes origin and extent. If you use this,
99 // *DO* give origin/extent arguments to wxMakeMetaFilePlaceable.
100 wxMetaFileDC::wxMetaFileDC(const wxString
& file
)
109 if (!file
.IsNull() && wxFileExists(file
))
111 m_hDC
= (WXHDC
) CreateMetaFile(file
);
115 // Actual Windows mapping mode, for future reference.
116 m_windowsMappingMode
= MM_TEXT
;
118 SetMapMode(MM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
121 // New constructor that takes origin and extent. If you use this, don't
122 // give origin/extent arguments to wxMakeMetaFilePlaceable.
123 wxMetaFileDC::wxMetaFileDC(const wxString
& file
, int xext
, int yext
, int xorg
, int yorg
)
129 if (file
!= "" && wxFileExists(file
)) wxRemoveFile(file
);
130 m_hDC
= (WXHDC
) CreateMetaFile(file
);
134 ::SetWindowOrgEx((HDC
) m_hDC
,xorg
,yorg
, NULL
);
135 ::SetWindowExtEx((HDC
) m_hDC
,xext
,yext
, NULL
);
137 // Actual Windows mapping mode, for future reference.
138 m_windowsMappingMode
= MM_ANISOTROPIC
;
140 SetMapMode(MM_TEXT
); // NOTE: does not set HDC mapmode (this is correct)
143 wxMetaFileDC::~wxMetaFileDC(void)
148 void wxMetaFileDC::GetTextExtent(const wxString
& string
, float *x
, float *y
,
149 float *descent
, float *externalLeading
, wxFont
*theFont
, bool use16bit
)
151 wxFont
*fontToUse
= theFont
;
155 HDC dc
= GetDC(NULL
);
159 GetTextExtentPoint(dc
, (char *)(const char *) string
, strlen((char *)(const char *) string
), &sizeRect
);
160 GetTextMetrics(dc
, &tm
);
164 *x
= (float)XDEV2LOGREL(sizeRect
.cx
);
165 *y
= (float)YDEV2LOGREL(sizeRect
.cy
);
166 if (descent
) *descent
= (float)tm
.tmDescent
;
167 if (externalLeading
) *externalLeading
= (float)tm
.tmExternalLeading
;
170 wxMetaFile
*wxMetaFileDC::Close(void)
172 SelectOldObjects(m_hDC
);
173 HANDLE mf
= CloseMetaFile((HDC
) m_hDC
);
177 wxMetaFile
*wx_mf
= new wxMetaFile
;
178 wx_mf
->SetHMETAFILE((WXHANDLE
) mf
);
179 wx_mf
->SetWindowsMappingMode(m_windowsMappingMode
);
185 void wxMetaFileDC::SetMapMode(int mode
)
187 m_mappingMode
= mode
;
189 // int pixel_width = 0;
190 // int pixel_height = 0;
192 // int mm_height = 0;
194 float mm2pixelsX
= 10.0;
195 float mm2pixelsY
= 10.0;
201 m_logicalScaleX
= (float)(twips2mm
* mm2pixelsX
);
202 m_logicalScaleY
= (float)(twips2mm
* mm2pixelsY
);
207 m_logicalScaleX
= (float)(pt2mm
* mm2pixelsX
);
208 m_logicalScaleY
= (float)(pt2mm
* mm2pixelsY
);
213 m_logicalScaleX
= mm2pixelsX
;
214 m_logicalScaleY
= mm2pixelsY
;
219 m_logicalScaleX
= (float)(mm2pixelsX
/10.0);
220 m_logicalScaleY
= (float)(mm2pixelsY
/10.0);
226 m_logicalScaleX
= 1.0;
227 m_logicalScaleY
= 1.0;
244 struct mfPLACEABLEHEADER
{
253 struct mfPLACEABLEHEADER
{
264 * Pass filename of existing non-placeable metafile, and bounding box.
265 * Adds a placeable metafile header, sets the mapping mode to anisotropic,
266 * and sets the window origin and extent to mimic the MM_TEXT mapping mode.
270 bool wxMakeMetaFilePlaceable(const wxString
& filename
, float scale
)
272 return wxMakeMetaFilePlaceable(filename
, 0, 0, 0, 0, scale
, FALSE
);
275 bool wxMakeMetaFilePlaceable(const wxString
& filename
, int x1
, int y1
, int x2
, int y2
, float scale
, bool useOriginAndExtent
)
277 // I'm not sure if this is the correct way of suggesting a scale
278 // to the client application, but it's the only way I can find.
279 int unitsPerInch
= (int)(576/scale
);
281 mfPLACEABLEHEADER header
;
282 header
.key
= 0x9AC6CDD7L
;
284 header
.bbox
.left
= (int)(x1
);
285 header
.bbox
.top
= (int)(y1
);
286 header
.bbox
.right
= (int)(x2
);
287 header
.bbox
.bottom
= (int)(y2
);
288 header
.inch
= unitsPerInch
;
291 // Calculate checksum
293 mfPLACEABLEHEADER
*pMFHead
= &header
;
294 for (p
=(WORD
*)pMFHead
,pMFHead
-> checksum
= 0;
295 p
< (WORD
*)&pMFHead
->checksum
; ++p
)
296 pMFHead
->checksum
^= *p
;
298 FILE *fd
= fopen((char *)(const char *)filename
, "rb");
299 if (!fd
) return FALSE
;
301 char tempFileBuf
[256];
302 wxGetTempFileName("mf", tempFileBuf
);
303 FILE *fHandle
= fopen(tempFileBuf
, "wb");
306 fwrite((void *)&header
, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER
), fHandle
);
308 // Calculate origin and extent
311 int extentX
= x2
- x1
;
312 int extentY
= (y2
- y1
);
314 // Read metafile header and write
315 METAHEADER metaHeader
;
316 fread((void *)&metaHeader
, sizeof(unsigned char), sizeof(metaHeader
), fd
);
318 if (useOriginAndExtent
)
319 metaHeader
.mtSize
+= 15;
321 metaHeader
.mtSize
+= 5;
323 fwrite((void *)&metaHeader
, sizeof(unsigned char), sizeof(metaHeader
), fHandle
);
325 // Write SetMapMode, SetWindowOrigin and SetWindowExt records
327 char originBuffer
[10];
328 char extentBuffer
[10];
329 METARECORD
*modeRecord
= (METARECORD
*)&modeBuffer
;
331 METARECORD
*originRecord
= (METARECORD
*)&originBuffer
;
332 METARECORD
*extentRecord
= (METARECORD
*)&extentBuffer
;
334 modeRecord
->rdSize
= 4;
335 modeRecord
->rdFunction
= META_SETMAPMODE
;
336 modeRecord
->rdParm
[0] = MM_ANISOTROPIC
;
338 originRecord
->rdSize
= 5;
339 originRecord
->rdFunction
= META_SETWINDOWORG
;
340 originRecord
->rdParm
[0] = originY
;
341 originRecord
->rdParm
[1] = originX
;
343 extentRecord
->rdSize
= 5;
344 extentRecord
->rdFunction
= META_SETWINDOWEXT
;
345 extentRecord
->rdParm
[0] = extentY
;
346 extentRecord
->rdParm
[1] = extentX
;
348 fwrite((void *)modeBuffer
, sizeof(char), 8, fHandle
);
350 if (useOriginAndExtent
)
352 fwrite((void *)originBuffer
, sizeof(char), 10, fHandle
);
353 fwrite((void *)extentBuffer
, sizeof(char), 10, fHandle
);
367 wxRemoveFile(filename
);
368 wxCopyFile(tempFileBuf
, filename
);
369 wxRemoveFile(tempFileBuf
);
373 #endif // USE_METAFILE