[95] | 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 |
|
---|