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