1 | /*
|
---|
2 | *********************************************************************
|
---|
3 | * File: ximawmf.cpp
|
---|
4 | * Purpose: Windows Metafile Class Loader and Writer
|
---|
5 | * Author: Volker Horch - vhorch@gmx.de
|
---|
6 | * created: 13-Jun-2002
|
---|
7 | *
|
---|
8 | * Note: If the code below works, i wrote it.
|
---|
9 | * If it doesn't work, i don't know who wrote it.
|
---|
10 | *********************************************************************
|
---|
11 | */
|
---|
12 |
|
---|
13 | /*
|
---|
14 | *********************************************************************
|
---|
15 | Note by Author:
|
---|
16 | *********************************************************************
|
---|
17 |
|
---|
18 | Metafile Formats:
|
---|
19 | =================
|
---|
20 |
|
---|
21 | There are 2 kinds of Windows Metafiles:
|
---|
22 | - Standard Windows Metafile
|
---|
23 | - Placeable Windows Metafile
|
---|
24 |
|
---|
25 | A StandardWindows Metafile looks like:
|
---|
26 | - Metafile Header (MEATAHEADER)
|
---|
27 | - Metafile Records
|
---|
28 |
|
---|
29 | A Placeable Metafile looks like:
|
---|
30 | - Aldus Header (METAFILEHEADER)
|
---|
31 | - Metafile Header (METAHEADER)
|
---|
32 | - Metafile Records
|
---|
33 |
|
---|
34 | The "Metafile Header" and the "Metafile Records" are the same
|
---|
35 | for both formats. However, the Standard Metafile does not contain any
|
---|
36 | information about the original dimensions or x/y ratio of the Metafile.
|
---|
37 |
|
---|
38 | I decided, to allow only placeable Metafiles here. If you also want to
|
---|
39 | enable Standard Metafiles, you will have to guess the dimensions of
|
---|
40 | the image.
|
---|
41 |
|
---|
42 | *********************************************************************
|
---|
43 | Limitations: see ximawmf.h
|
---|
44 | you may configure some stuff there
|
---|
45 | *********************************************************************
|
---|
46 | */
|
---|
47 |
|
---|
48 | #include "ximawmf.h"
|
---|
49 |
|
---|
50 | #if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
|
---|
51 |
|
---|
52 | ////////////////////////////////////////////////////////////////////////////////
|
---|
53 | #if CXIMAGE_SUPPORT_DECODE
|
---|
54 | ////////////////////////////////////////////////////////////////////////////////
|
---|
55 | bool CxImageWMF::Decode(CxFile *hFile, long nForceWidth, long nForceHeight)
|
---|
56 | {
|
---|
57 | if (hFile == NULL) return false;
|
---|
58 |
|
---|
59 | HENHMETAFILE hMeta;
|
---|
60 | HDC hDC;
|
---|
61 | int cx,cy;
|
---|
62 |
|
---|
63 | //save the current position of the file
|
---|
64 | long pos = hFile->Tell();
|
---|
65 |
|
---|
66 | // Read the Metafile and convert to an Enhanced Metafile
|
---|
67 | METAFILEHEADER mfh;
|
---|
68 | hMeta = ConvertWmfFiletoEmf(hFile, &mfh);
|
---|
69 | if (hMeta) { // ok, it's a WMF
|
---|
70 |
|
---|
71 | /////////////////////////////////////////////////////////////////////
|
---|
72 | // We use the original WMF size information, because conversion to
|
---|
73 | // EMF adjusts the Metafile to Full Screen or does not set rclBounds at all
|
---|
74 | // ENHMETAHEADER emh;
|
---|
75 | // UINT uRet;
|
---|
76 | // uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
|
---|
77 | // sizeof(ENHMETAHEADER), // size of buffer, in bytes
|
---|
78 | // &emh); // address of buffer to receive data
|
---|
79 | // if (!uRet){
|
---|
80 | // DeleteEnhMetaFile(hMeta);
|
---|
81 | // return false;
|
---|
82 | // }
|
---|
83 | // // calculate size
|
---|
84 | // cx = emh.rclBounds.right - emh.rclBounds.left;
|
---|
85 | // cy = emh.rclBounds.bottom - emh.rclBounds.top;
|
---|
86 | /////////////////////////////////////////////////////////////////////
|
---|
87 |
|
---|
88 | // calculate size
|
---|
89 | // scale the metafile (pixels/inch of metafile => pixels/inch of display)
|
---|
90 | // mfh.inch already checked to be <> 0
|
---|
91 |
|
---|
92 | hDC = ::GetDC(0);
|
---|
93 | int cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
---|
94 | int cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
---|
95 | ::ReleaseDC(0, hDC);
|
---|
96 |
|
---|
97 | cx = (mfh.inch/2 + (mfh.bbox.right - mfh.bbox.left) * cx1) / mfh.inch;
|
---|
98 | cy = (mfh.inch/2 + (mfh.bbox.bottom - mfh.bbox.top) * cy1) / mfh.inch;
|
---|
99 |
|
---|
100 | } else { // maybe it's an EMF...
|
---|
101 |
|
---|
102 | hFile->Seek(pos,SEEK_SET);
|
---|
103 |
|
---|
104 | ENHMETAHEADER emh;
|
---|
105 | hMeta = ConvertEmfFiletoEmf(hFile, &emh);
|
---|
106 |
|
---|
107 | if (!hMeta){
|
---|
108 | strcpy(info.szLastError,"corrupted WMF");
|
---|
109 | return false; // definitively give up
|
---|
110 | }
|
---|
111 |
|
---|
112 | // ok, it's an EMF; calculate canvas size
|
---|
113 | cx = emh.rclBounds.right - emh.rclBounds.left;
|
---|
114 | cy = emh.rclBounds.bottom - emh.rclBounds.top;
|
---|
115 |
|
---|
116 | // alternative methods, sometime not so reliable... [DP]
|
---|
117 | //cx = emh.szlDevice.cx;
|
---|
118 | //cy = emh.szlDevice.cy;
|
---|
119 | //
|
---|
120 | //hDC = ::GetDC(0);
|
---|
121 | //float hscale = (float)GetDeviceCaps(hDC, HORZRES)/(100.0f * GetDeviceCaps(hDC, HORZSIZE));
|
---|
122 | //float vscale = (float)GetDeviceCaps(hDC, VERTRES)/(100.0f * GetDeviceCaps(hDC, VERTSIZE));
|
---|
123 | //::ReleaseDC(0, hDC);
|
---|
124 | //cx = (long)((emh.rclFrame.right - emh.rclFrame.left) * hscale);
|
---|
125 | //cy = (long)((emh.rclFrame.bottom - emh.rclFrame.top) * vscale);
|
---|
126 | }
|
---|
127 |
|
---|
128 | if (info.nEscape == -1) { // Check if cancelled
|
---|
129 | head.biWidth = cx;
|
---|
130 | head.biHeight= cy;
|
---|
131 | info.dwType = CXIMAGE_FORMAT_WMF;
|
---|
132 | DeleteEnhMetaFile(hMeta);
|
---|
133 | strcpy(info.szLastError,"output dimensions returned");
|
---|
134 | return true;
|
---|
135 | }
|
---|
136 |
|
---|
137 | if (!cx || !cy) {
|
---|
138 | DeleteEnhMetaFile(hMeta);
|
---|
139 | strcpy(info.szLastError,"empty WMF");
|
---|
140 | return false;
|
---|
141 | }
|
---|
142 |
|
---|
143 | if (nForceWidth) cx=nForceWidth;
|
---|
144 | if (nForceHeight) cy=nForceHeight;
|
---|
145 | ShrinkMetafile(cx, cy); // !! Otherwise Bitmap may have bombastic size
|
---|
146 |
|
---|
147 | HDC hDC0 = ::GetDC(0); // DC of screen
|
---|
148 | HBITMAP hBitmap = CreateCompatibleBitmap(hDC0, cx, cy); // has # colors of display
|
---|
149 | hDC = CreateCompatibleDC(hDC0); // memory dc compatible with screen
|
---|
150 | ::ReleaseDC(0, hDC0); // don't need anymore. get rid of it.
|
---|
151 |
|
---|
152 | if (hDC){
|
---|
153 | if (hBitmap){
|
---|
154 | RECT rc = {0,0,cx,cy};
|
---|
155 | int bpp = ::GetDeviceCaps(hDC, BITSPIXEL);
|
---|
156 |
|
---|
157 | HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap);
|
---|
158 |
|
---|
159 | // clear out the entire bitmap with windows background
|
---|
160 | // because the MetaFile may not contain background information
|
---|
161 | DWORD dwBack = XMF_COLOR_BACK;
|
---|
162 | #if XMF_SUPPORT_TRANSPARENCY
|
---|
163 | if (bpp == 24) dwBack = XMF_COLOR_TRANSPARENT;
|
---|
164 | #endif
|
---|
165 | DWORD OldColor = SetBkColor(hDC, dwBack);
|
---|
166 | ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
|
---|
167 | SetBkColor(hDC, OldColor);
|
---|
168 |
|
---|
169 | //retrieves optional palette entries from the specified enhanced metafile
|
---|
170 | PLOGPALETTE plogPal;
|
---|
171 | PBYTE pjTmp;
|
---|
172 | HPALETTE hPal;
|
---|
173 | int iEntries = GetEnhMetaFilePaletteEntries(hMeta, 0, NULL);
|
---|
174 | if (iEntries) {
|
---|
175 | if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
|
---|
176 | sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
|
---|
177 | DeleteObject(hBitmap);
|
---|
178 | DeleteDC(hDC);
|
---|
179 | DeleteEnhMetaFile(hMeta);
|
---|
180 | strcpy(info.szLastError,"Cancelled");
|
---|
181 | return false;
|
---|
182 | }
|
---|
183 |
|
---|
184 | plogPal->palVersion = 0x300;
|
---|
185 | plogPal->palNumEntries = (WORD) iEntries;
|
---|
186 | pjTmp = (PBYTE) plogPal;
|
---|
187 | pjTmp += 4;
|
---|
188 |
|
---|
189 | GetEnhMetaFilePaletteEntries(hMeta, iEntries, (PPALETTEENTRY)pjTmp);
|
---|
190 | hPal = CreatePalette(plogPal);
|
---|
191 | GlobalFree(plogPal);
|
---|
192 |
|
---|
193 | SelectPalette(hDC, hPal, FALSE);
|
---|
194 | RealizePalette(hDC);
|
---|
195 | }
|
---|
196 |
|
---|
197 | // Play the Metafile into Memory DC
|
---|
198 | BOOL bRet = PlayEnhMetaFile(hDC, // handle to a device context
|
---|
199 | hMeta, // handle to an enhanced metafile
|
---|
200 | &rc); // pointer to bounding rectangle
|
---|
201 |
|
---|
202 | SelectObject(hDC, hBitmapOld);
|
---|
203 | DeleteEnhMetaFile(hMeta); // we are done with this one
|
---|
204 |
|
---|
205 | if (info.nEscape) { // Check if cancelled
|
---|
206 | DeleteObject(hBitmap);
|
---|
207 | DeleteDC(hDC);
|
---|
208 | strcpy(info.szLastError,"Cancelled");
|
---|
209 | return false;
|
---|
210 | }
|
---|
211 |
|
---|
212 | // the Bitmap now has the image.
|
---|
213 | // Create our DIB and convert the DDB into DIB
|
---|
214 | if (!Create(cx, cy, bpp, CXIMAGE_FORMAT_WMF)) {
|
---|
215 | DeleteObject(hBitmap);
|
---|
216 | DeleteDC(hDC);
|
---|
217 | return false;
|
---|
218 | }
|
---|
219 |
|
---|
220 | #if XMF_SUPPORT_TRANSPARENCY
|
---|
221 | if (bpp == 24) {
|
---|
222 | RGBQUAD rgbTrans = { XMF_RGBQUAD_TRANSPARENT };
|
---|
223 | SetTransColor(rgbTrans);
|
---|
224 | }
|
---|
225 | #endif
|
---|
226 | // We're finally ready to get the DIB. Call the driver and let
|
---|
227 | // it party on our bitmap. It will fill in the color table,
|
---|
228 | // and bitmap bits of our global memory block.
|
---|
229 | bRet = GetDIBits(hDC, hBitmap, 0,
|
---|
230 | (UINT)cy, GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
|
---|
231 |
|
---|
232 | DeleteObject(hBitmap);
|
---|
233 | DeleteDC(hDC);
|
---|
234 |
|
---|
235 | return (bRet!=0);
|
---|
236 | } else {
|
---|
237 | DeleteDC(hDC);
|
---|
238 | }
|
---|
239 | } else {
|
---|
240 | if (hBitmap) DeleteObject(hBitmap);
|
---|
241 | }
|
---|
242 |
|
---|
243 | DeleteEnhMetaFile(hMeta);
|
---|
244 |
|
---|
245 | return false;
|
---|
246 | }
|
---|
247 |
|
---|
248 | /**********************************************************************
|
---|
249 | Function: CheckMetafileHeader
|
---|
250 | Purpose: Check if the Metafileheader of a file is valid
|
---|
251 | **********************************************************************/
|
---|
252 | BOOL CxImageWMF::CheckMetafileHeader(METAFILEHEADER *metafileheader)
|
---|
253 | {
|
---|
254 | WORD *pw;
|
---|
255 | WORD cs;
|
---|
256 | int i;
|
---|
257 |
|
---|
258 | // check magic #
|
---|
259 | if (metafileheader->key != 0x9ac6cdd7L) return false;
|
---|
260 |
|
---|
261 | // test checksum of header
|
---|
262 | pw = (WORD *)metafileheader;
|
---|
263 | cs = *pw;
|
---|
264 | pw++;
|
---|
265 | for (i = 0; i < 9; i++) {
|
---|
266 | cs ^= *pw;
|
---|
267 | pw++;
|
---|
268 | }
|
---|
269 |
|
---|
270 | if (cs != metafileheader->checksum) return false;
|
---|
271 |
|
---|
272 | // check resolution
|
---|
273 | if ((metafileheader->inch <= 0) || (metafileheader->inch > 2540)) return false;
|
---|
274 |
|
---|
275 | return true;
|
---|
276 | }
|
---|
277 |
|
---|
278 | /**********************************************************************
|
---|
279 | Function: ConvertWmfFiletoEmf
|
---|
280 | Purpose: Converts a Windows Metafile into an Enhanced Metafile
|
---|
281 | **********************************************************************/
|
---|
282 | HENHMETAFILE CxImageWMF::ConvertWmfFiletoEmf(CxFile *fp, METAFILEHEADER *metafileheader)
|
---|
283 | {
|
---|
284 | HENHMETAFILE hMeta;
|
---|
285 | long lenFile;
|
---|
286 | long len;
|
---|
287 | BYTE *p;
|
---|
288 | METAHEADER mfHeader;
|
---|
289 | DWORD seekpos;
|
---|
290 |
|
---|
291 | hMeta = 0;
|
---|
292 |
|
---|
293 | // get length of the file
|
---|
294 | lenFile = fp->Size();
|
---|
295 |
|
---|
296 | // a placeable metafile starts with a METAFILEHEADER
|
---|
297 | // read it and check metafileheader
|
---|
298 | len = fp->Read(metafileheader, 1, sizeof(METAFILEHEADER));
|
---|
299 | if (len < sizeof(METAFILEHEADER)) return (hMeta);
|
---|
300 |
|
---|
301 | if (CheckMetafileHeader(metafileheader)) {
|
---|
302 | // This is a placeable metafile
|
---|
303 | // Convert the placeable format into something that can
|
---|
304 | // be used with GDI metafile functions
|
---|
305 | seekpos = sizeof(METAFILEHEADER);
|
---|
306 | } else {
|
---|
307 | // Not a placeable wmf. A windows metafile?
|
---|
308 | // at least not scaleable.
|
---|
309 | // we could try to convert, but would loose ratio. don't allow this
|
---|
310 | return (hMeta);
|
---|
311 |
|
---|
312 | //metafileheader->bbox.right = ?;
|
---|
313 | //metafileheader->bbox.left = ?;
|
---|
314 | //metafileheader->bbox.bottom = ?;
|
---|
315 | //metafileheader->bbox.top = ?;
|
---|
316 | //metafileheader->inch = ?;
|
---|
317 | //
|
---|
318 | //seekpos = 0;
|
---|
319 | // fp->Seek(0, SEEK_SET); // rewind
|
---|
320 | }
|
---|
321 |
|
---|
322 | // At this point we have a metaheader regardless of whether
|
---|
323 | // the metafile was a windows metafile or a placeable metafile
|
---|
324 | // so check to see if it is valid. There is really no good
|
---|
325 | // way to do this so just make sure that the mtType is either
|
---|
326 | // 1 or 2 (memory or disk file)
|
---|
327 | // in addition we compare the length of the METAHEADER against
|
---|
328 | // the length of the file. if filelength < len => no Metafile
|
---|
329 |
|
---|
330 | len = fp->Read(&mfHeader, 1, sizeof(METAHEADER));
|
---|
331 | if (len < sizeof(METAHEADER)) return (hMeta);
|
---|
332 |
|
---|
333 | if ((mfHeader.mtType != 1) && (mfHeader.mtType != 2)) return (hMeta);
|
---|
334 |
|
---|
335 | // Length in Bytes from METAHEADER
|
---|
336 | len = mfHeader.mtSize * 2;
|
---|
337 | if (len > lenFile) return (hMeta);
|
---|
338 |
|
---|
339 | // Allocate memory for the metafile bits
|
---|
340 | p = (BYTE *)malloc(len);
|
---|
341 | if (!p) return (hMeta);
|
---|
342 |
|
---|
343 | // seek back to METAHEADER and read all the stuff at once
|
---|
344 | fp->Seek(seekpos, SEEK_SET);
|
---|
345 | lenFile = fp->Read(p, 1, len);
|
---|
346 | if (lenFile != len) {
|
---|
347 | free(p);
|
---|
348 | return (hMeta);
|
---|
349 | }
|
---|
350 |
|
---|
351 | // the following (commented code) works, but adjusts rclBound of the
|
---|
352 | // Enhanced Metafile to full screen.
|
---|
353 | // the METAFILEHEADER from above is needed to scale the image
|
---|
354 |
|
---|
355 | // hMeta = SetWinMetaFileBits(len, p, NULL, NULL);
|
---|
356 |
|
---|
357 | // scale the metafile (pixels/inch of metafile => pixels/inch of display)
|
---|
358 |
|
---|
359 | METAFILEPICT mfp;
|
---|
360 | int cx1, cy1;
|
---|
361 | HDC hDC;
|
---|
362 |
|
---|
363 | hDC = ::GetDC(0);
|
---|
364 | cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
|
---|
365 | cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
|
---|
366 |
|
---|
367 | memset(&mfp, 0, sizeof(mfp));
|
---|
368 |
|
---|
369 | mfp.mm = MM_ANISOTROPIC;
|
---|
370 | mfp.xExt = 10000; //(metafileheader->bbox.right - metafileheader->bbox.left) * cx1 / metafileheader->inch;
|
---|
371 | mfp.yExt = 10000; //(metafileheader->bbox.bottom - metafileheader->bbox.top) * cy1 / metafileheader->inch;
|
---|
372 | mfp.hMF = 0;
|
---|
373 |
|
---|
374 | // in MM_ANISOTROPIC mode xExt and yExt are in MM_HIENGLISH
|
---|
375 | // MM_HIENGLISH means: Each logical unit is converted to 0.001 inch
|
---|
376 | //mfp.xExt *= 1000;
|
---|
377 | //mfp.yExt *= 1000;
|
---|
378 | // ????
|
---|
379 | //int k = 332800 / ::GetSystemMetrics(SM_CXSCREEN);
|
---|
380 | //mfp.xExt *= k; mfp.yExt *= k;
|
---|
381 |
|
---|
382 | // fix for Win9x
|
---|
383 | while ((mfp.xExt < 6554) && (mfp.yExt < 6554))
|
---|
384 | {
|
---|
385 | mfp.xExt *= 10;
|
---|
386 | mfp.yExt *= 10;
|
---|
387 | }
|
---|
388 |
|
---|
389 | hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
|
---|
390 |
|
---|
391 | if (!hMeta){ //try 2nd conversion using a different mapping
|
---|
392 | mfp.mm = MM_TEXT;
|
---|
393 | hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
|
---|
394 | }
|
---|
395 |
|
---|
396 | ::ReleaseDC(0, hDC);
|
---|
397 |
|
---|
398 | // Free Memory
|
---|
399 | free(p);
|
---|
400 |
|
---|
401 | return (hMeta);
|
---|
402 | }
|
---|
403 | /////////////////////////////////////////////////////////////////////
|
---|
404 | HENHMETAFILE CxImageWMF::ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh)
|
---|
405 | {
|
---|
406 | HENHMETAFILE hMeta;
|
---|
407 | long iLen = pFile->Size();
|
---|
408 |
|
---|
409 | // Check the header first: <km>
|
---|
410 | long pos = pFile->Tell();
|
---|
411 | long iLenRead = pFile->Read(pemfh, 1, sizeof(ENHMETAHEADER));
|
---|
412 | if (iLenRead < sizeof(ENHMETAHEADER)) return NULL;
|
---|
413 | if (pemfh->iType != EMR_HEADER) return NULL;
|
---|
414 | if (pemfh->dSignature != ENHMETA_SIGNATURE) return NULL;
|
---|
415 | //if (pemfh->nBytes != (DWORD)iLen) return NULL;
|
---|
416 | pFile->Seek(pos,SEEK_SET);
|
---|
417 |
|
---|
418 | BYTE* pBuff = (BYTE *)malloc(iLen);
|
---|
419 | if (!pBuff) return (FALSE);
|
---|
420 |
|
---|
421 | // Read the Enhanced Metafile
|
---|
422 | iLenRead = pFile->Read(pBuff, 1, iLen);
|
---|
423 | if (iLenRead != iLen) {
|
---|
424 | free(pBuff);
|
---|
425 | return NULL;
|
---|
426 | }
|
---|
427 |
|
---|
428 | // Make it a Memory Metafile
|
---|
429 | hMeta = SetEnhMetaFileBits(iLen, pBuff);
|
---|
430 |
|
---|
431 | free(pBuff); // finished with this one
|
---|
432 |
|
---|
433 | if (!hMeta) return NULL; // oops.
|
---|
434 |
|
---|
435 | // Get the Enhanced Metafile Header
|
---|
436 | UINT uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
|
---|
437 | sizeof(ENHMETAHEADER), // size of buffer, in bytes
|
---|
438 | pemfh); // address of buffer to receive data
|
---|
439 |
|
---|
440 | if (!uRet) {
|
---|
441 | DeleteEnhMetaFile(hMeta);
|
---|
442 | return NULL;
|
---|
443 | }
|
---|
444 |
|
---|
445 | return (hMeta);
|
---|
446 | }
|
---|
447 | ////////////////////////////////////////////////////////////////////////////////
|
---|
448 | #endif //CXIMAGE_SUPPORT_DECODE
|
---|
449 | ////////////////////////////////////////////////////////////////////////////////
|
---|
450 | #if CXIMAGE_SUPPORT_ENCODE
|
---|
451 | /////////////////////////////////////////////////////////////////////
|
---|
452 | bool CxImageWMF::Encode(CxFile * hFile)
|
---|
453 | {
|
---|
454 | if (hFile == NULL) return false;
|
---|
455 | strcpy(info.szLastError, "Save WMF not supported");
|
---|
456 | return false;
|
---|
457 | }
|
---|
458 | #endif // CXIMAGE_SUPPORT_ENCODE
|
---|
459 | /////////////////////////////////////////////////////////////////////
|
---|
460 |
|
---|
461 | /**********************************************************************
|
---|
462 | Function: ShrinkMetafile
|
---|
463 | Purpose: Shrink the size of a metafile to be not larger than
|
---|
464 | the definition
|
---|
465 | **********************************************************************/
|
---|
466 | void CxImageWMF::ShrinkMetafile(int &cx, int &cy)
|
---|
467 | {
|
---|
468 | int xScreen = XMF_MAXSIZE_CX;
|
---|
469 | int yScreen = XMF_MAXSIZE_CY;
|
---|
470 |
|
---|
471 | if (cx > xScreen){
|
---|
472 | cy = cy * xScreen / cx;
|
---|
473 | cx = xScreen;
|
---|
474 | }
|
---|
475 |
|
---|
476 | if (cy > yScreen){
|
---|
477 | cx = cx * yScreen / cy;
|
---|
478 | cy = yScreen;
|
---|
479 | }
|
---|
480 | }
|
---|
481 |
|
---|
482 | #endif // CIMAGE_SUPPORT_WMF
|
---|
483 |
|
---|