352 lines
7.6 KiB
C++
352 lines
7.6 KiB
C++
|
|
||
|
/*++
|
||
|
|
||
|
Copyright (c) 1992 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
ddecnvrt.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module contains the code to read/write PBrush, MSDraw native data
|
||
|
formats. This module also contains PBrush native format <->DIbFile stream,
|
||
|
and MSDraw native format <-> placeable metafile stream conversion routines.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Srini Koppolu (srinik) 06/29/1993
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <le2int.h>
|
||
|
#include <ole1cls.h>
|
||
|
#ifndef _MAC
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/************************ FILE FORMATS **********************************
|
||
|
|
||
|
|
||
|
Normal Metafile (memory or disk based):
|
||
|
|
||
|
------------ ---------------
|
||
|
| METAHEADER | Metafile bits |
|
||
|
------------ ---------------
|
||
|
|
||
|
Placeable Metafile:
|
||
|
|
||
|
--------------------- -----------------
|
||
|
| PLACEABLEMETAHEADER | Normal metafile |
|
||
|
--------------------- -----------------
|
||
|
|
||
|
Memory Based DIB:
|
||
|
|
||
|
------------------ --------------- ----------
|
||
|
| BITMAPINFOHEADER | RGBQUAD array | DIB bits |
|
||
|
------------------ --------------- ----------
|
||
|
|
||
|
DIB file format:
|
||
|
|
||
|
------------------ ------------------
|
||
|
| BITMAPFILEHEADER | Memory based DIB |
|
||
|
------------------ ------------------
|
||
|
|
||
|
Ole10NativeStream Format:
|
||
|
|
||
|
-------- ----------------------
|
||
|
| dwSize | Object's Native data |
|
||
|
-------- ----------------------
|
||
|
|
||
|
PBrush Native data format:
|
||
|
|
||
|
-----------------
|
||
|
| Dib File format |
|
||
|
-----------------
|
||
|
|
||
|
MSDraw Native data format:
|
||
|
|
||
|
--------------------- ------------- ------------- -----------------
|
||
|
| mapping mode (WORD) | xExt (WORD) | yExt (WORD) | Normal metafile |
|
||
|
--------------------- ------------- ------------- -----------------
|
||
|
|
||
|
|
||
|
*****************************************************************************/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
FARINTERNAL UtGetHMFPICTFromMSDrawNativeStm
|
||
|
(LPSTREAM pstm, DWORD dwSize, HANDLE FAR* lphdata)
|
||
|
{
|
||
|
HRESULT error;
|
||
|
WORD mfp[3]; // mm, xExt, yExt
|
||
|
HMETAFILE hMF = NULL;
|
||
|
|
||
|
*lphdata = NULL;
|
||
|
|
||
|
if (error = pstm->Read(mfp, sizeof(mfp), NULL))
|
||
|
return error;
|
||
|
|
||
|
dwSize -= sizeof(mfp);
|
||
|
|
||
|
if (error = UtGetHMFFromMFStm(pstm, dwSize, FALSE, (void **)&hMF))
|
||
|
return error;
|
||
|
|
||
|
AssertSz(mfp[0] == MM_ANISOTROPIC, "invalid map mode in MsDraw native data");
|
||
|
|
||
|
if (*lphdata = UtGetHMFPICT(hMF, TRUE, (int) mfp[1], (int) mfp[2]))
|
||
|
return NOERROR;
|
||
|
|
||
|
return ResultFromScode(E_OUTOFMEMORY);
|
||
|
}
|
||
|
|
||
|
|
||
|
FARINTERNAL UtPlaceableMFStmToMSDrawNativeStm
|
||
|
(LPSTREAM pstmPMF, LPSTREAM pstmMSDraw)
|
||
|
{
|
||
|
DWORD dwSize; // size of metafile bits excluding the placeable MF header
|
||
|
LONG xExt;
|
||
|
LONG yExt;
|
||
|
WORD wBuf[5]; // dwSize(DWORD), mm(int), xExt(int), yExt(int)
|
||
|
HRESULT error;
|
||
|
|
||
|
if (error = UtGetSizeAndExtentsFromPlaceableMFStm(pstmPMF, &dwSize,
|
||
|
&xExt, &yExt))
|
||
|
return error;
|
||
|
|
||
|
*((DWORD FAR*) wBuf) = dwSize + 3*sizeof(WORD);
|
||
|
wBuf[2] = MM_ANISOTROPIC;
|
||
|
wBuf[3] = (int) xExt;
|
||
|
wBuf[4] = (int) yExt;
|
||
|
|
||
|
if (error = pstmMSDraw->Write(wBuf, sizeof(wBuf), 0))
|
||
|
return error;
|
||
|
|
||
|
ULARGE_INTEGER ularge_int;
|
||
|
ULISet32(ularge_int, dwSize);
|
||
|
if ((error = pstmPMF->CopyTo(pstmMSDraw, ularge_int,
|
||
|
NULL, NULL)) == NOERROR)
|
||
|
StSetSize(pstmMSDraw, 0, TRUE);
|
||
|
|
||
|
return error;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
FARINTERNAL UtDIBFileStmToPBrushNativeStm
|
||
|
(LPSTREAM pstmDIBFile, LPSTREAM pstmPBrush)
|
||
|
{
|
||
|
BITMAPFILEHEADER bfh;
|
||
|
HRESULT error;
|
||
|
|
||
|
if (error = pstmDIBFile->Read(&bfh, sizeof(bfh), 0))
|
||
|
return error;
|
||
|
|
||
|
// seek to the begining of the stream
|
||
|
LARGE_INTEGER large_int;
|
||
|
LISet32( large_int, 0);
|
||
|
if (error = pstmDIBFile->Seek(large_int, STREAM_SEEK_SET, 0))
|
||
|
return error;
|
||
|
|
||
|
if (error = pstmPBrush->Write(&(bfh.bfSize), sizeof(DWORD), 0))
|
||
|
return error;
|
||
|
|
||
|
ULARGE_INTEGER ularge_int;
|
||
|
ULISet32(ularge_int, bfh.bfSize);
|
||
|
|
||
|
if ((error = pstmDIBFile->CopyTo(pstmPBrush, ularge_int,
|
||
|
NULL, NULL)) == NOERROR)
|
||
|
StSetSize(pstmPBrush, 0, TRUE);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
FARINTERNAL UtContentsStmTo10NativeStm
|
||
|
(LPSTORAGE pstg, REFCLSID rclsid, BOOL fDeleteSrcStm, UINT FAR* puiStatus)
|
||
|
{
|
||
|
CLIPFORMAT cf;
|
||
|
LPOLESTR lpszUserType = NULL;
|
||
|
HRESULT error;
|
||
|
LPSTREAM pstmSrc = NULL;
|
||
|
LPSTREAM pstmDst = NULL;
|
||
|
|
||
|
*puiStatus = NULL;
|
||
|
|
||
|
if (error = ReadFmtUserTypeStg(pstg, &cf, &lpszUserType))
|
||
|
return error;
|
||
|
|
||
|
|
||
|
if (! ((cf == CF_DIB && rclsid == CLSID_PBrush)
|
||
|
|| (cf == CF_METAFILEPICT && rclsid == CLSID_MSDraw))) {
|
||
|
error = ResultFromScode(DV_E_CLIPFORMAT);
|
||
|
goto errRtn;
|
||
|
}
|
||
|
|
||
|
if (error = pstg->OpenStream(OLE_CONTENTS_STREAM, NULL,
|
||
|
(STGM_READ|STGM_SHARE_EXCLUSIVE),
|
||
|
0, &pstmSrc)) {
|
||
|
*puiStatus |= CONVERT_NOSOURCE;
|
||
|
|
||
|
// check whether OLE10_NATIVE_STREAM exists
|
||
|
if (pstg->OpenStream(OLE10_NATIVE_STREAM, NULL,
|
||
|
(STGM_READ|STGM_SHARE_EXCLUSIVE), 0, &pstmDst))
|
||
|
*puiStatus |= CONVERT_NODESTINATION;
|
||
|
else {
|
||
|
pstmDst->Release();
|
||
|
pstmDst = NULL;
|
||
|
}
|
||
|
|
||
|
goto errRtn;
|
||
|
}
|
||
|
|
||
|
if (error = OpenOrCreateStream(pstg, OLE10_NATIVE_STREAM, &pstmDst)) {
|
||
|
*puiStatus |= CONVERT_NODESTINATION;
|
||
|
goto errRtn;
|
||
|
}
|
||
|
|
||
|
if (cf == CF_METAFILEPICT)
|
||
|
error = UtPlaceableMFStmToMSDrawNativeStm(pstmSrc, pstmDst);
|
||
|
else
|
||
|
error = UtDIBFileStmToPBrushNativeStm(pstmSrc, pstmDst);
|
||
|
|
||
|
errRtn:
|
||
|
if (pstmDst)
|
||
|
pstmDst->Release();
|
||
|
|
||
|
if (pstmSrc)
|
||
|
pstmSrc->Release();
|
||
|
|
||
|
if (error == NOERROR) {
|
||
|
LPOLESTR lpszProgId = NULL;
|
||
|
ProgIDFromCLSID(rclsid, &lpszProgId);
|
||
|
|
||
|
error = WriteFmtUserTypeStg(pstg,
|
||
|
(CLIPFORMAT) RegisterClipboardFormat(lpszProgId),
|
||
|
lpszUserType);
|
||
|
|
||
|
if (lpszProgId)
|
||
|
delete lpszProgId;
|
||
|
}
|
||
|
|
||
|
if (error == NOERROR) {
|
||
|
if (fDeleteSrcStm)
|
||
|
pstg->DestroyElement(OLE_CONTENTS_STREAM);
|
||
|
} else {
|
||
|
pstg->DestroyElement(OLE10_NATIVE_STREAM);
|
||
|
}
|
||
|
|
||
|
if (lpszUserType)
|
||
|
delete lpszUserType;
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
FARINTERNAL Ut10NativeStmToContentsStm
|
||
|
(LPSTORAGE pstg, REFCLSID rclsid, BOOL fDeleteSrcStm)
|
||
|
{
|
||
|
|
||
|
CLIPFORMAT cfOld;
|
||
|
CLIPFORMAT cfNew;
|
||
|
LPOLESTR lpszUserType = NULL;
|
||
|
HRESULT error;
|
||
|
LPSTREAM pstmSrc = NULL;
|
||
|
LPSTREAM pstmDst = NULL;
|
||
|
|
||
|
|
||
|
if (error = ReadFmtUserTypeStg(pstg, &cfOld, &lpszUserType))
|
||
|
return error;
|
||
|
|
||
|
if (rclsid == CLSID_StaticDib)
|
||
|
cfNew = CF_DIB;
|
||
|
else if (rclsid == CLSID_StaticMetafile)
|
||
|
cfNew = CF_METAFILEPICT;
|
||
|
else {
|
||
|
AssertSz(FALSE, "Internal Error: this routine shouldn't have been called for this class");
|
||
|
return ResultFromScode(E_FAIL);
|
||
|
}
|
||
|
|
||
|
if (cfOld == g_cfPBrush) {
|
||
|
if (cfNew != CF_DIB) {
|
||
|
error = ResultFromScode(DV_E_CLIPFORMAT);
|
||
|
goto errRtn;
|
||
|
}
|
||
|
} else if (cfOld == g_cfMSDraw) {
|
||
|
if (cfNew != CF_METAFILEPICT) {
|
||
|
error = ResultFromScode(DV_E_CLIPFORMAT);
|
||
|
goto errRtn;
|
||
|
}
|
||
|
} else {
|
||
|
// Converted to static object from some class other than PBrush or
|
||
|
// MSDraw. The data must be in a proper format in the CONTENTS
|
||
|
// stream.
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
if (error = pstg->OpenStream(OLE10_NATIVE_STREAM, NULL,
|
||
|
(STGM_READ|STGM_SHARE_EXCLUSIVE),
|
||
|
0, &pstmSrc))
|
||
|
goto errRtn;
|
||
|
|
||
|
if (error = OpenOrCreateStream(pstg, OLE_CONTENTS_STREAM, &pstmDst))
|
||
|
goto errRtn;
|
||
|
|
||
|
DWORD dwSize;
|
||
|
if (error = pstmSrc->Read(&dwSize, sizeof(DWORD), NULL))
|
||
|
goto errRtn;
|
||
|
|
||
|
if (cfOld == g_cfMSDraw) {
|
||
|
WORD mfp[3]; // mm, xExt, yExt
|
||
|
|
||
|
if (error = pstmSrc->Read(mfp, sizeof(mfp), NULL))
|
||
|
goto errRtn;
|
||
|
|
||
|
dwSize -= sizeof(mfp);
|
||
|
|
||
|
error = UtMFStmToPlaceableMFStm(pstmSrc, dwSize,
|
||
|
(LONG) mfp[1], (LONG) mfp[2], pstmDst);
|
||
|
|
||
|
} else {
|
||
|
// The PBrush native data format is DIB File format. So all we got to
|
||
|
// do is CopyTo.
|
||
|
|
||
|
ULARGE_INTEGER ularge_int;
|
||
|
ULISet32(ularge_int, dwSize);
|
||
|
if ((error = pstmSrc->CopyTo(pstmDst, ularge_int, NULL,
|
||
|
NULL)) == NOERROR)
|
||
|
StSetSize(pstmDst, 0, TRUE);
|
||
|
}
|
||
|
|
||
|
errRtn:
|
||
|
if (pstmDst)
|
||
|
pstmDst->Release();
|
||
|
|
||
|
if (pstmSrc)
|
||
|
pstmSrc->Release();
|
||
|
|
||
|
if (error == NOERROR) {
|
||
|
error = WriteFmtUserTypeStg(pstg, cfNew, lpszUserType);
|
||
|
|
||
|
if (fDeleteSrcStm)
|
||
|
pstg->DestroyElement(OLE10_NATIVE_STREAM);
|
||
|
|
||
|
} else {
|
||
|
pstg->DestroyElement(OLE_CONTENTS_STREAM);
|
||
|
}
|
||
|
|
||
|
if (lpszUserType)
|
||
|
PubMemFree(lpszUserType);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|