int CMetafileDisplay::LoadBits(UINT uiBuf, LPVOID pBuf) { #pragma pack(2) typedef struct { DWORD key; WORD hmf; short left; short top; short right; short bottom; WORD inch; DWORD reserved; WORD checksum; } AMETAHEADER; #pragma pack() if (enhMF != NULL) { DeleteEnhMetaFile(enhMF); enhMF = NULL; } // See if this is an enhanced metafile ENHMETAHEADER *emhdr = (ENHMETAHEADER *)pBuf; if (uiBuf >= sizeof(ENHMETAHEADER) && emhdr->iType == EMR_HEADER && emhdr->dSignature == ENHMETA_SIGNATURE) { enhMF = SetEnhMetaFileBits(uiBuf, (CONST BYTE *)pBuf); } else if (uiBuf >= sizeof(METAHEADER)) { METAFILEPICT mp = {MM_ANISOTROPIC, 1000, 1000, NULL}; AMETAHEADER *ahdr = (AMETAHEADER *)pBuf; METAHEADER *mhdr = (METAHEADER *)pBuf; // See if this is a placeable metafile if (ahdr->key == 0x9AC6CDD7) { mp.xExt = ((LONG)(ahdr->right - ahdr->left) * 25401) / (LONG)ahdr->inch; mp.yExt = ((LONG)(ahdr->bottom - ahdr->top) * 25401) / (LONG)ahdr->inch; mhdr = (METAHEADER *) (ahdr + 1); } UINT uiSizeMF = (UINT) mhdr->mtSize * 2; HDC dcRef = ::GetDC(NULL); enhMF = SetWinMetaFileBits(uiSizeMF, (LPBYTE)mhdr, dcRef, &mp); ::ReleaseDC(NULL, dcRef); } return (enhMF == NULL) ? -1 : 0; }
/* void VPictureData_GDIPlus_Vector::FromVFile(VFile& inFile) { Gdiplus::Rect rect; SetDataSource(NULL,true); _DisposeMetaFile(); _SetDecoderByExtension("emf"); VString path; inFile.GetPath(path); fMetafile=new Gdiplus::Metafile(path.GetCPointer()); _InitSize(); } */ void VPictureData_GDIPlus_Vector::_FromMetaFilePict(METAFILEPICT* inMetaPict) { HENHMETAFILE henh; void* lpWinMFBits; UINT uiSizeBuf; uiSizeBuf = GetMetaFileBitsEx(inMetaPict->hMF, 0, NULL); lpWinMFBits = GlobalAllocPtr(GHND, uiSizeBuf); GetMetaFileBitsEx(inMetaPict->hMF, uiSizeBuf, (LPVOID)lpWinMFBits); henh = SetWinMetaFileBits(uiSizeBuf, (LPBYTE)lpWinMFBits, NULL, inMetaPict); GlobalFreePtr(lpWinMFBits); _FromEnhMetaFile(henh); }
void VPictureData_EMF::FromMetaFilePict(METAFILEPICT* inMetaPict) { HENHMETAFILE henh; _ReleaseDataProvider(); _DisposeMetaFile(); void* lpWinMFBits; UINT uiSizeBuf; uiSizeBuf = GetMetaFileBitsEx(inMetaPict->hMF, 0, NULL); lpWinMFBits = GlobalAllocPtr(GHND, uiSizeBuf); GetMetaFileBitsEx(inMetaPict->hMF, uiSizeBuf, (LPVOID)lpWinMFBits); henh = SetWinMetaFileBits(uiSizeBuf, (LPBYTE)lpWinMFBits, NULL, inMetaPict); GlobalFreePtr(lpWinMFBits); FromEnhMetaFile(henh); }
void PlayPlaceableMeta(HDC hdc,BYTE *pMeta,int len,RECT *rt) { HENHMETAFILE hEnh; PAPMHEADER pHeader=(PAPMHEADER)pMeta; METAFILEPICT mp; if(pHeader->dwKey == 0x9ac6cdd7l) { mp.mm = MM_ANISOTROPIC; mp.xExt = pHeader->bbox.Right - pHeader->bbox.Left; mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(pHeader->wInch); mp.yExt = pHeader->bbox.Bottom - pHeader->bbox.Top; mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(pHeader->wInch); mp.hMF = NULL; hEnh = SetWinMetaFileBits(len, &(pMeta[sizeof(APMHEADER)]), hdc, &mp); PlayEnhMetaFile(hdc,hEnh,rt); DeleteEnhMetaFile(hEnh); } }
/********************************************************************** Function: ConvertWmfFiletoEmf Purpose: Converts a Windows Metafile into an Enhanced Metafile **********************************************************************/ HENHMETAFILE CxImageWMF::ConvertWmfFiletoEmf(CxFile *fp, METAFILEHEADER *metafileheader) { HENHMETAFILE hMeta; long lenFile; long len; BYTE *p; METAHEADER mfHeader; DWORD seekpos; hMeta = 0; // get length of the file lenFile = fp->Size(); // a placeable metafile starts with a METAFILEHEADER // read it and check metafileheader len = fp->Read(metafileheader, 1, sizeof(METAFILEHEADER)); if (len < sizeof(METAFILEHEADER)) return (hMeta); if (CheckMetafileHeader(metafileheader)) { // This is a placeable metafile // Convert the placeable format into something that can // be used with GDI metafile functions seekpos = sizeof(METAFILEHEADER); } else { // Not a placeable wmf. A windows metafile? // at least not scaleable. // we could try to convert, but would loose ratio. don't allow this return (hMeta); //metafileheader->bbox.right = ?; //metafileheader->bbox.left = ?; //metafileheader->bbox.bottom = ?; //metafileheader->bbox.top = ?; //metafileheader->inch = ?; // //seekpos = 0; // fp->Seek(0, SEEK_SET); // rewind } // At this point we have a metaheader regardless of whether // the metafile was a windows metafile or a placeable metafile // so check to see if it is valid. There is really no good // way to do this so just make sure that the mtType is either // 1 or 2 (memory or disk file) // in addition we compare the length of the METAHEADER against // the length of the file. if filelength < len => no Metafile len = fp->Read(&mfHeader, 1, sizeof(METAHEADER)); if (len < sizeof(METAHEADER)) return (hMeta); if ((mfHeader.mtType != 1) && (mfHeader.mtType != 2)) return (hMeta); // Length in Bytes from METAHEADER len = mfHeader.mtSize * 2; if (len > lenFile) return (hMeta); // Allocate memory for the metafile bits p = (BYTE *)malloc(len); if (!p) return (hMeta); // seek back to METAHEADER and read all the stuff at once fp->Seek(seekpos, SEEK_SET); lenFile = fp->Read(p, 1, len); if (lenFile != len) { free(p); return (hMeta); } // the following (commented code) works, but adjusts rclBound of the // Enhanced Metafile to full screen. // the METAFILEHEADER from above is needed to scale the image // hMeta = SetWinMetaFileBits(len, p, NULL, NULL); // scale the metafile (pixels/inch of metafile => pixels/inch of display) METAFILEPICT mfp; int cx1, cy1; HDC hDC; hDC = ::GetDC(0); cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX); cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY); memset(&mfp, 0, sizeof(mfp)); mfp.mm = MM_ANISOTROPIC; mfp.xExt = (metafileheader->bbox.right - metafileheader->bbox.left) * cx1 / metafileheader->inch; mfp.yExt = (metafileheader->bbox.bottom - metafileheader->bbox.top) * cy1 / metafileheader->inch; mfp.hMF = 0; // in MM_ANISOTROPIC mode xExt and yExt are in MM_HIENGLISH // MM_HIENGLISH means: Each logical unit is converted to 0.001 inch //mfp.xExt *= 1000; //mfp.yExt *= 1000; // ???? //int k = 332800 / ::GetSystemMetrics(SM_CXSCREEN); //mfp.xExt *= k; mfp.yExt *= k; // fix for Win9x while ((mfp.xExt < 6554) && (mfp.yExt < 6554)) { mfp.xExt *= 10; mfp.yExt *= 10; } hMeta = SetWinMetaFileBits(len, p, hDC, &mfp); if (!hMeta){ //try 2nd conversion using a different mapping mfp.mm = MM_TEXT; hMeta = SetWinMetaFileBits(len, p, hDC, &mfp); } ::ReleaseDC(0, hDC); // Free Memory free(p); return (hMeta); }
static HENHMETAFILE ReadEnhMetaFile(const char *path,long *width, long *height) { #pragma pack( push ) #pragma pack( 2 ) typedef struct { DWORD dwKey; WORD hmf; SMALL_RECT bbox; WORD wInch; DWORD dwReserved; WORD wCheckSum; } APMHEADER, *PAPMHEADER; #pragma pack( pop ) DWORD dwSize; ENHMETAHEADER emfh; HANDLE hFile; HDC hDC; HENHMETAFILE hTemp; LPBYTE pBits; METAFILEPICT mp; HMETAFILE hOld; *width=512; *height=512; hTemp=GetEnhMetaFile(path); #if defined(MAGICKCORE_HAVE__WFOPEN) if (hTemp == (HENHMETAFILE) NULL) { wchar_t *unicode_path; unicode_path=ConvertUTF8ToUTF16(path); if (unicode_path != (wchar_t *) NULL) { hTemp=GetEnhMetaFileW(unicode_path); unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path); } } #endif if (hTemp != (HENHMETAFILE) NULL) { /* Enhanced metafile. */ GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } hOld=GetMetaFile(path); if (hOld != (HMETAFILE) NULL) { /* 16bit windows metafile. */ dwSize=GetMetaFileBitsEx(hOld,0,NULL); if (dwSize == 0) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits)); if (pBits == (LPBYTE) NULL) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0) { pBits=(BYTE *) DestroyString((char *) pBits); DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the windows metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=1000; mp.yExt=1000; mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp); ReleaseDC(NULL,hDC); DeleteMetaFile(hOld); pBits=(BYTE *) DestroyString((char *) pBits); GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } /* Aldus Placeable metafile. */ hFile=CreateFile(path,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return(NULL); dwSize=GetFileSize(hFile,NULL); pBits=(LPBYTE) AcquireQuantumMemory(dwSize,sizeof(*pBits)); ReadFile(hFile,pBits,dwSize,&dwSize,NULL); CloseHandle(hFile); if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l) { pBits=(BYTE *) DestroyString((char *) pBits); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the placable metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left; *width=mp.xExt; mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top; *height=mp.yExt; mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp); ReleaseDC(NULL,hDC); pBits=(BYTE *) DestroyString((char *) pBits); return(hTemp); }
void PLWEMFDecoder::Open (PLDataSource * pDataSrc) { PLASSERT_VALID(this); PLASSERT(m_bm == 0); PLASSERT(m_memdc == 0); PLASSERT(m_hemf == 0); SAPMFILEHEADER* pplaceablehdr = NULL; bool isadobe = false; bool isemf; // Get the type of the file (WMF or EMF) from the file name if (pDataSrc->NameIsWide()){ wchar_t* strname = _wcsdup(pDataSrc->GetNameW()); PLASSERT(strname); if (strname == NULL) { // This should never happen under 32-Bit, but who knows? PLASSERT(false); raiseError (PL_ERRNO_MEMORY,"Out of memory during strdup."); } _wcsupr(strname); isemf = wcsstr(strname,L".EMF") != NULL; free(strname); } else{ char* strname = _strdup(pDataSrc->GetName()); PLASSERT(strname); if (strname == NULL) { // This should never happen under 32-Bit, but who knows? PLASSERT(false); raiseError (PL_ERRNO_MEMORY,"Out of memory during strdup."); } _strupr(strname); bool isemf = strstr(strname,".EMF") != NULL; free(strname); } // Get a DC for the display m_dc = ::GetDC(NULL); PLASSERT(m_dc); if (m_dc == NULL) { PLASSERT(false); raiseError (PL_ERRNO_MEMORY,"Cannot allocate device context."); } if (isemf) { // We have an enhanced meta file which makes it alot easier m_hemf = SetEnhMetaFileBits(pDataSrc->GetFileSize(),pDataSrc->ReadEverything()); } else { // Buh, old 16-Bit WMF, Convert it to an enhanced metafile before proceeding. // Also, check if this is a placeable metafile with an Adobe Placeable header pplaceablehdr = (SAPMFILEHEADER*)pDataSrc->ReadEverything(); PLBYTE* p = NULL; UINT size; // If we have an adobe header, skip it to use only the real windows-conform data if (pplaceablehdr->key == ALDUSKEY) { isadobe = true; p = pDataSrc->ReadEverything()+sizeof(SAPMFILEHEADER); size = pDataSrc->GetFileSize() - sizeof(SAPMFILEHEADER); } else { // Else use the whole file contents as the metafile and assume // a native 16-Bit Windows-conform WMF p = pDataSrc->ReadEverything(); size = pDataSrc->GetFileSize(); } #ifdef _MFC_VER PLASSERT(AfxIsValidAddress(p,size,false)); #endif m_hemf = SetWinMetaFileBits(size,p,m_dc,NULL); } // If m_hemf is NULL, windows refused to load the metafile. If this is // the case, we're done. Notify the caller if (m_hemf == NULL) { raiseError (PL_ERRFORMAT_NOT_SUPPORTED,"Windows Metafile functions failed to load this image."); } // Get the header from the enhanced metafile, It contains some // useful information which will aid us during constuction of // the bitmap. // The header is of variable length. First get the amount of // memory required for the header UINT sizeneeded = GetEnhMetaFileHeader(m_hemf,0,NULL); if (sizeneeded == 0) { raiseError (PL_ERRFORMAT_UNKNOWN,"No header information in metafile"); } // Allocate storage for the header and read it in m_phdr = (LPENHMETAHEADER) new PLBYTE[sizeneeded]; if (m_phdr == NULL) { PLASSERT(false); raiseError (PL_ERRNO_MEMORY,"Out of memory during allocation of header."); } m_phdr->iType = EMR_HEADER; m_phdr->nSize = sizeneeded; #ifdef _MFC_VER PLASSERT(AfxIsValidAddress(m_phdr,sizeneeded,true)); #endif GetEnhMetaFileHeader(m_hemf,sizeneeded,m_phdr); int bpp = GetDeviceCaps(m_dc,BITSPIXEL); // Calculate the dimensions of the final bitmap. If we have // a placeable header in the WMF, we use the dimensions of // that image, else we use the calculated dimensions in the // EMF int width,height; if (isadobe) { PLASSERT(pplaceablehdr); int lpx = GetDeviceCaps(m_dc,LOGPIXELSX); int lpy = GetDeviceCaps(m_dc,LOGPIXELSY); // Calculate the absolute with and height and transform from twips to pixel width = (int) (pplaceablehdr->Right-pplaceablehdr->Left) * lpx / pplaceablehdr->inch; height = (int) (pplaceablehdr->Bottom-pplaceablehdr->Top) * lpy / pplaceablehdr->inch; } else { // Use the rclFrame of the header because it is the true device independent // information and also some applications (e.g. Corel) don't fill the // rclBounds correctly // Using: // MetaPixelsX = MetaWidthMM * MetaPixels / (MetaMM * 100); // where: // MetaWidthMM = metafile width in 0.01mm units // MetaPixels = width in pixels of the reference device // MetaMM = width in millimeters of the reference device // Same applies to the Y axis width = ((m_phdr->rclFrame.right - m_phdr->rclFrame.left) * m_phdr->szlDevice.cx) / (m_phdr->szlMillimeters.cx*100); height = ((m_phdr->rclFrame.bottom - m_phdr->rclFrame.top) * m_phdr->szlDevice.cy) / (m_phdr->szlMillimeters.cy*100); } // If this is a very old WMF without a PLACEABLE info, // we use somewhat meaningful defaults. Also, if the header was // not written correctly, we use this as a fallback if (width <= 0) { width = 320; } if (height <= 0) { height = 200; } // Create a device content for the screen, and a memory device // content to play the metafile to m_memdc = CreateCompatibleDC(m_dc); PLASSERT(m_memdc); if (m_memdc == NULL) { PLASSERT(false); raiseError (PL_ERRNO_MEMORY,"Cannot allocate device context."); } m_bm = CreateCompatibleBitmap(m_dc,width,height); if (m_bm == NULL) { PLASSERT(false); raiseError (PL_ERRNO_MEMORY,"Cannot allocate memory bitmap."); } m_holdbm = SelectObject(m_memdc,m_bm); // If the metafile has a palette, read it in UINT pe = GetEnhMetaFilePaletteEntries(m_hemf, 0, NULL); // pe is the real number of palette entries. To make the resulting // bitmap more useful, we always setup a 256 color palette if the // metafile has a palette if (pe>0 && pe<256) { SetBmpInfo (PLPoint (width, height), PLPoint(0,0), PLPixelFormat::L8); } else { SetBmpInfo (PLPoint (width, height), PLPoint(0,0), PLPixelFormat::B8G8R8A8); } }
PyObject * PyImaging_DrawWmf(PyObject* self, PyObject* args) { HBITMAP bitmap; HENHMETAFILE meta; BITMAPCOREHEADER core; HDC dc; RECT rect; PyObject* buffer = NULL; char* ptr; char* data; int datasize; int width, height; int x0, y0, x1, y1; if (!PyArg_ParseTuple(args, PY_ARG_BYTES_LENGTH"(ii)(iiii):_load", &data, &datasize, &width, &height, &x0, &x1, &y0, &y1)) return NULL; /* step 1: copy metafile contents into METAFILE object */ if (datasize > 22 && GET32(data, 0) == 0x9ac6cdd7) { /* placeable windows metafile (22-byte aldus header) */ meta = SetWinMetaFileBits(datasize-22, data+22, NULL, NULL); } else if (datasize > 80 && GET32(data, 0) == 1 && GET32(data, 40) == 0x464d4520) { /* enhanced metafile */ meta = SetEnhMetaFileBits(datasize, data); } else { /* unknown meta format */ meta = NULL; } if (!meta) { PyErr_SetString(PyExc_IOError, "cannot load metafile"); return NULL; } /* step 2: create bitmap */ core.bcSize = sizeof(core); core.bcWidth = width; core.bcHeight = height; core.bcPlanes = 1; core.bcBitCount = 24; dc = CreateCompatibleDC(NULL); bitmap = CreateDIBSection( dc, (BITMAPINFO*) &core, DIB_RGB_COLORS, &ptr, NULL, 0 ); if (!bitmap) { PyErr_SetString(PyExc_IOError, "cannot create bitmap"); goto error; } if (!SelectObject(dc, bitmap)) { PyErr_SetString(PyExc_IOError, "cannot select bitmap"); goto error; } /* step 3: render metafile into bitmap */ rect.left = rect.top = 0; rect.right = width; rect.bottom = height; /* FIXME: make background transparent? configurable? */ FillRect(dc, &rect, GetStockObject(WHITE_BRUSH)); if (!PlayEnhMetaFile(dc, meta, &rect)) { PyErr_SetString(PyExc_IOError, "cannot render metafile"); goto error; } /* step 4: extract bits from bitmap */ GdiFlush(); buffer = PyBytes_FromStringAndSize(ptr, height * ((width*3 + 3) & -4)); error: DeleteEnhMetaFile(meta); if (bitmap) DeleteObject(bitmap); DeleteDC(dc); return buffer; }
BOOL __stdcall pvdFileOpen2(void *pContext, const wchar_t *pFileName, INT64 lFileSize, const BYTE *pBuf, UINT32 lBuf, pvdInfoImage2 *pImageInfo) { _ASSERTE(pImageInfo->cbSize >= sizeof(pvdInfoImage2)); WmfContext *pw = (WmfContext*)CALLOC(sizeof(WmfContext)); if (!pw) { pImageInfo->nErrNumber = PWE_NOT_ENOUGH_MEMORY; return FALSE; } //pw->h = GetEnhMetaFile ( pFileName+4 ); const wchar_t *p = GetExtension(pFileName); if (!p) { pImageInfo->nErrNumber = PWE_NO_EXTENSION; return FALSE; } pImageInfo->nErrNumber = PWE_WIN32_ERROR; // заранее //if (pImageInfo->PreferredSize.cx && pImageInfo->PreferredSize.cy) { // pw->PreferredSize = pImageInfo->PreferredSize; //} else { pw->PreferredSize.cx = 1000; pw->PreferredSize.cy = 1000; //} // First try to read it as an enhanced metafile // If it works, simply return the handle pw->h = SetEnhMetaFileBits(lBuf, pBuf); gnLastWin32Error = GetLastError(); if (!pw->h) { pw->h = GetEnhMetaFile( pFileName ); gnLastWin32Error = GetLastError(); } if (!pw->h) { HMETAFILE hOld; DWORD dwSize; LPBYTE pBits; METAFILEPICT mp; HDC hDC; if( (hOld = GetMetaFile( pFileName )) != NULL ) { // Ok, it is a 16bit windows metafile // How big are the bits? if( (dwSize = GetMetaFileBitsEx( hOld, 0, NULL )) == 0 ) { gnLastWin32Error = GetLastError(); DeleteMetaFile( hOld ); //MessageBox( hWndParent, "Failed to Get MetaFile Bits Size", "Error Reading MetaFile", MB_OK ); } else { // Allocate that much memory if( (pBits = (LPBYTE)CALLOC( dwSize )) == NULL ) { pImageInfo->nErrNumber = PWE_NOT_ENOUGH_MEMORY; gnLastWin32Error = GetLastError(); DeleteMetaFile( hOld ); //MessageBox( hWndParent, "Failed to Allocate Memory for Metafile Bits", "Error Reading MetaFile", MB_OK ); //return NULL; } else { // Get the metafile bits if( GetMetaFileBitsEx( hOld, dwSize, pBits ) == 0 ) { gnLastWin32Error = GetLastError(); FREE( pBits ); DeleteMetaFile( hOld ); //MessageBox( hWndParent, "Failed to Get MetaFile Bits", "Error Reading MetaFile", MB_OK ); //return NULL; } else { // Fill out a METAFILEPICT structure mp.mm = MM_ANISOTROPIC; mp.xExt = 1000; mp.yExt = 1000; mp.hMF = NULL; // Get a reference DC hDC = GetDC( NULL ); // Make an enhanced metafile from the windows metafile pw->h = SetWinMetaFileBits( dwSize, pBits, hDC, &mp ); gnLastWin32Error = GetLastError(); // Clean up ReleaseDC( NULL, hDC ); DeleteMetaFile( hOld ); FREE( pBits ); } } } } } if (!pw->h) { DWORD dwSize = lBuf; LPBYTE pBits = (LPBYTE)pBuf; METAFILEPICT mp; HDC hDC; // Is it a placeable metafile? (check the key) if( ((PAPMHEADER)pBits)->dwKey != 0x9ac6cdd7l ) { // Not a metafile that we know how to recognise - bail out //MessageBox( hWndParent, "Not a Valid Metafile", szFileName, MB_OK ); //return NULL; pImageInfo->nErrNumber = PWE_NOT_VALID_METAFILE; } else { // Ok, its a placeable metafile // Fill out a METAFILEPICT structure mp.mm = MM_ANISOTROPIC; mp.xExt = ((PAPMHEADER)pBits)->bbox.Right - ((PAPMHEADER)pBits)->bbox.Left; mp.xExt = ( mp.xExt * 2540l ) / (DWORD)(((PAPMHEADER)pBits)->wInch); mp.yExt = ((PAPMHEADER)pBits)->bbox.Bottom - ((PAPMHEADER)pBits)->bbox.Top; mp.yExt = ( mp.yExt * 2540l ) / (DWORD)(((PAPMHEADER)pBits)->wInch); mp.hMF = NULL; // Get a reference DC hDC = GetDC( NULL ); // Create an enhanced metafile from the bits pw->h = SetWinMetaFileBits( dwSize, &(pBits[sizeof(APMHEADER)]), hDC, &mp ); gnLastWin32Error = GetLastError(); // Clean up ReleaseDC( NULL, hDC ); //free( pBits ); //if( hTemp == NULL ) // MessageBox( hWndParent, "Failed to Create MetaFile from Bits", "Error Reading MetaFile", MB_OK ); //return hTemp; } } //if (pw->h) { // //pw->hCompDC = CreateCompatibleDC(NULL); // pw->mfp.mm = MM_ISOTROPIC; // pw->mfp.xExt = pw->PreferredSize.cx; // pw->mfp.yExt = pw->PreferredSize.cy; // pw->h = (HENHMETAFILE)SetMetaFileBitsEx (lBuf, pBuf); // gnLastWin32Error = GetLastError(); // pw->h = SetWinMetaFileBits(lBuf, pBuf, NULL, NULL); //pw->hCompDC, &pw->mfp); // gnLastWin32Error = GetLastError(); //} if (!pw->h) { //gnLastWin32Error = GetLastError(); -- уже FREE(pw); return FALSE; } pw->AddRef(); _ASSERTE(pw->nRefCount == 1); ENHMETAHEADER emh = {0}; DWORD PixelsX, PixelsY, MMX, MMY; emh.nSize = sizeof(ENHMETAHEADER); if( GetEnhMetaFileHeader( pw->h, sizeof( ENHMETAHEADER ), &emh ) ) { // Get the characteristics of the output device HDC hDC = GetDC(NULL); PixelsX = GetDeviceCaps( hDC, HORZRES ); PixelsY = GetDeviceCaps( hDC, VERTRES ); MMX = GetDeviceCaps( hDC, HORZSIZE ) * 100; MMY = GetDeviceCaps( hDC, VERTSIZE ) * 100; ReleaseDC(NULL, hDC); // Calculate the rect in which to draw the metafile based on the // intended size and the current output device resolution // Remember that the intended size is given in 0.01mm units, so // convert those to device units on the target device //pw->PreferredSize.cx = (int)((float)(emh.rclFrame.right - emh.rclFrame.left) * PixelsX / (MMX)); //pw->PreferredSize.cy = (int)((float)(emh.rclFrame.bottom - emh.rclFrame.top) * PixelsY / (MMY)); pw->PreferredSize.cx = ip.MulDivI32((emh.rclFrame.right - emh.rclFrame.left), PixelsX, MMX); pw->PreferredSize.cy = ip.MulDivI32((emh.rclFrame.bottom - emh.rclFrame.top), PixelsY, MMY); _ASSERTE(pw->PreferredSize.cx>0 && pw->PreferredSize.cy>0); if (pw->PreferredSize.cx < 0) pw->PreferredSize.cx = -pw->PreferredSize.cx; if (pw->PreferredSize.cy < 0) pw->PreferredSize.cy = -pw->PreferredSize.cy; } pImageInfo->pImageContext = pw; pImageInfo->nPages = 1; pImageInfo->Flags = 0; pImageInfo->pFormatName = L"WMF"; pImageInfo->pCompression = NULL; pImageInfo->pComments = NULL; return TRUE; }
static HENHMETAFILE ReadEnhMetaFile(const char *szFileName,long *width, long *height) { #pragma pack( push, 2 ) typedef struct { DWORD dwKey; WORD hmf; SMALL_RECT bbox; WORD wInch; DWORD dwReserved; WORD wCheckSum; } APMHEADER, *PAPMHEADER; #pragma pack( pop ) DWORD dwSize; ENHMETAHEADER emfh; HANDLE hFile; HDC hDC; HENHMETAFILE hTemp; LPBYTE pBits; METAFILEPICT mp; HMETAFILE hOld; *width=512; *height=512; hTemp=GetEnhMetaFile(szFileName); if (hTemp != (HENHMETAFILE) NULL) { /* Enhanced metafile. */ GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } hOld=GetMetaFile(szFileName); if (hOld != (HMETAFILE) NULL) { /* 16bit windows metafile. */ dwSize=GetMetaFileBitsEx(hOld,0,NULL); if (dwSize == 0) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } pBits=MagickAllocateMemory(LPBYTE,dwSize); if (pBits == (LPBYTE) NULL) { DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } if (GetMetaFileBitsEx(hOld,dwSize,pBits) == 0) { MagickFreeMemory(pBits); DeleteMetaFile(hOld); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the windows metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=1000; mp.yExt=1000; mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,pBits,hDC,&mp); ReleaseDC(NULL,hDC); DeleteMetaFile(hOld); MagickFreeMemory(pBits); GetEnhMetaFileHeader(hTemp,sizeof(ENHMETAHEADER),&emfh); *width=emfh.rclFrame.right-emfh.rclFrame.left; *height=emfh.rclFrame.bottom-emfh.rclFrame.top; return(hTemp); } /* Aldus Placeable metafile. */ hFile=CreateFile(szFileName,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); if (hFile == INVALID_HANDLE_VALUE) return(NULL); dwSize=GetFileSize(hFile,NULL); pBits=MagickAllocateMemory(LPBYTE,dwSize); ReadFile(hFile,pBits,dwSize,&dwSize,NULL); CloseHandle(hFile); if (((PAPMHEADER) pBits)->dwKey != 0x9ac6cdd7l) { MagickFreeMemory(pBits); return((HENHMETAFILE) NULL); } /* Make an enhanced metafile from the placable metafile. */ mp.mm=MM_ANISOTROPIC; mp.xExt=((PAPMHEADER) pBits)->bbox.Right-((PAPMHEADER) pBits)->bbox.Left; *width=mp.xExt; mp.xExt=(mp.xExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.yExt=((PAPMHEADER)pBits)->bbox.Bottom-((PAPMHEADER) pBits)->bbox.Top; *height=mp.yExt; mp.yExt=(mp.yExt*2540l)/(DWORD) (((PAPMHEADER) pBits)->wInch); mp.hMF=NULL; hDC=GetDC(NULL); hTemp=SetWinMetaFileBits(dwSize,&(pBits[sizeof(APMHEADER)]),hDC,&mp); ReleaseDC(NULL,hDC); MagickFreeMemory(pBits); return(hTemp); }