]> git.saurik.com Git - wxWidgets.git/blob - src/motif/metafile.cpp
Committing in .
[wxWidgets.git] / src / motif / metafile.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: metafile.cpp
3 // Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional.
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "metafile.h"
14 #endif
15
16 #include "wx/object.h"
17 #include "wx/string.h"
18 #include "wx/dc.h"
19 #include "wx/motif/metafile.h"
20 #include "wx/clipbrd.h"
21
22 extern bool wxClipboardIsOpen;
23
24 IMPLEMENT_DYNAMIC_CLASS(wxMetaFile, wxObject)
25 IMPLEMENT_ABSTRACT_CLASS(wxMetaFileDC, wxDC)
26
27 wxMetaFile::wxMetaFile(const wxString& file)
28 {
29 // TODO
30 }
31
32 wxMetaFile::~wxMetaFile()
33 {
34 // TODO
35 }
36
37 bool wxMetaFile::SetClipboard(int width, int height)
38 {
39 bool alreadyOpen=wxClipboardOpen();
40 if (!alreadyOpen)
41 {
42 wxOpenClipboard();
43 if (!wxEmptyClipboard()) return FALSE;
44 }
45 bool success = wxSetClipboardData(wxDF_METAFILE,this, width,height);
46 if (!alreadyOpen) wxCloseClipboard();
47 return (bool) success;
48 }
49
50 bool wxMetaFile::Play(wxDC *dc)
51 {
52 // TODO
53 return FALSE;
54 }
55
56 /*
57 * Metafile device context
58 *
59 */
60
61 // Original constructor that does not takes origin and extent. If you use this,
62 // *DO* give origin/extent arguments to wxMakeMetaFilePlaceable.
63 wxMetaFileDC::wxMetaFileDC(const wxString& file)
64 {
65 // TODO
66 }
67
68 // New constructor that takes origin and extent. If you use this, don't
69 // give origin/extent arguments to wxMakeMetaFilePlaceable.
70 wxMetaFileDC::wxMetaFileDC(const wxString& file, int xext, int yext, int xorg, int yorg)
71 {
72 // TODO
73 }
74
75 wxMetaFileDC::~wxMetaFileDC()
76 {
77 }
78
79 void wxMetaFileDC::GetTextExtent(const wxString& string, float *x, float *y,
80 float *descent, float *externalLeading, wxFont *theFont, bool use16bit)
81 {
82 // TODO
83 }
84
85 wxMetaFile *wxMetaFileDC::Close()
86 {
87 // TODO
88 return NULL;
89 }
90
91 void wxMetaFileDC::SetMapMode(int mode)
92 {
93 // TODO
94 }
95
96 #if 0
97
98 #ifdef __WIN32__
99 struct RECT32
100 {
101 short left;
102 short top;
103 short right;
104 short bottom;
105 };
106
107 struct mfPLACEABLEHEADER {
108 DWORD key;
109 short hmf;
110 RECT32 bbox;
111 WORD inch;
112 DWORD reserved;
113 WORD checksum;
114 };
115 #else
116 struct mfPLACEABLEHEADER {
117 DWORD key;
118 HANDLE hmf;
119 RECT bbox;
120 WORD inch;
121 DWORD reserved;
122 WORD checksum;
123 };
124 #endif
125
126 /*
127 * Pass filename of existing non-placeable metafile, and bounding box.
128 * Adds a placeable metafile header, sets the mapping mode to anisotropic,
129 * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode.
130 *
131 */
132
133 bool wxMakeMetaFilePlaceable(const wxString& filename, float scale)
134 {
135 return wxMakeMetaFilePlaceable(filename, 0, 0, 0, 0, scale, FALSE);
136 }
137
138 bool wxMakeMetaFilePlaceable(const wxString& filename, int x1, int y1, int x2, int y2, float scale, bool useOriginAndExtent)
139 {
140 // I'm not sure if this is the correct way of suggesting a scale
141 // to the client application, but it's the only way I can find.
142 int unitsPerInch = (int)(576/scale);
143
144 mfPLACEABLEHEADER header;
145 header.key = 0x9AC6CDD7L;
146 header.hmf = 0;
147 header.bbox.left = (int)(x1);
148 header.bbox.top = (int)(y1);
149 header.bbox.right = (int)(x2);
150 header.bbox.bottom = (int)(y2);
151 header.inch = unitsPerInch;
152 header.reserved = 0;
153
154 // Calculate checksum
155 WORD *p;
156 mfPLACEABLEHEADER *pMFHead = &header;
157 for (p =(WORD *)pMFHead,pMFHead -> checksum = 0;
158 p < (WORD *)&pMFHead ->checksum; ++p)
159 pMFHead ->checksum ^= *p;
160
161 FILE *fd = fopen((char *)(const char *)filename, "rb");
162 if (!fd) return FALSE;
163
164 char tempFileBuf[256];
165 wxGetTempFileName("mf", tempFileBuf);
166 FILE *fHandle = fopen(tempFileBuf, "wb");
167 if (!fHandle)
168 return FALSE;
169 fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle);
170
171 // Calculate origin and extent
172 int originX = x1;
173 int originY = y1;
174 int extentX = x2 - x1;
175 int extentY = (y2 - y1);
176
177 // Read metafile header and write
178 METAHEADER metaHeader;
179 fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd);
180
181 if (useOriginAndExtent)
182 metaHeader.mtSize += 15;
183 else
184 metaHeader.mtSize += 5;
185
186 fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle);
187
188 // Write SetMapMode, SetWindowOrigin and SetWindowExt records
189 char modeBuffer[8];
190 char originBuffer[10];
191 char extentBuffer[10];
192 METARECORD *modeRecord = (METARECORD *)&modeBuffer;
193
194 METARECORD *originRecord = (METARECORD *)&originBuffer;
195 METARECORD *extentRecord = (METARECORD *)&extentBuffer;
196
197 modeRecord->rdSize = 4;
198 modeRecord->rdFunction = META_SETMAPMODE;
199 modeRecord->rdParm[0] = wxMM_ANISOTROPIC;
200
201 originRecord->rdSize = 5;
202 originRecord->rdFunction = META_SETWINDOWORG;
203 originRecord->rdParm[0] = originY;
204 originRecord->rdParm[1] = originX;
205
206 extentRecord->rdSize = 5;
207 extentRecord->rdFunction = META_SETWINDOWEXT;
208 extentRecord->rdParm[0] = extentY;
209 extentRecord->rdParm[1] = extentX;
210
211 fwrite((void *)modeBuffer, sizeof(char), 8, fHandle);
212
213 if (useOriginAndExtent)
214 {
215 fwrite((void *)originBuffer, sizeof(char), 10, fHandle);
216 fwrite((void *)extentBuffer, sizeof(char), 10, fHandle);
217 }
218
219 int ch = -2;
220 while (ch != EOF)
221 {
222 ch = getc(fd);
223 if (ch != EOF)
224 {
225 putc(ch, fHandle);
226 }
227 }
228 fclose(fHandle);
229 fclose(fd);
230 wxRemoveFile(filename);
231 wxCopyFile(tempFileBuf, filename);
232 wxRemoveFile(tempFileBuf);
233 return TRUE;
234 }
235
236 #endif
237