Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
7.6 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ddecnvrt.cpp
  5. Abstract:
  6. This module contains the code to read/write PBrush, MSDraw native data
  7. formats. This module also contains PBrush native format <->DIbFile stream,
  8. and MSDraw native format <-> placeable metafile stream conversion routines.
  9. Author:
  10. Srini Koppolu (srinik) 06/29/1993
  11. Revision History:
  12. --*/
  13. #include <le2int.h>
  14. #include <ole1cls.h>
  15. #ifndef _MAC
  16. /************************ FILE FORMATS **********************************
  17. Normal Metafile (memory or disk based):
  18. ------------ ---------------
  19. | METAHEADER | Metafile bits |
  20. ------------ ---------------
  21. Placeable Metafile:
  22. --------------------- -----------------
  23. | PLACEABLEMETAHEADER | Normal metafile |
  24. --------------------- -----------------
  25. Memory Based DIB:
  26. ------------------ --------------- ----------
  27. | BITMAPINFOHEADER | RGBQUAD array | DIB bits |
  28. ------------------ --------------- ----------
  29. DIB file format:
  30. ------------------ ------------------
  31. | BITMAPFILEHEADER | Memory based DIB |
  32. ------------------ ------------------
  33. Ole10NativeStream Format:
  34. -------- ----------------------
  35. | dwSize | Object's Native data |
  36. -------- ----------------------
  37. PBrush Native data format:
  38. -----------------
  39. | Dib File format |
  40. -----------------
  41. MSDraw Native data format:
  42. --------------------- ------------- ------------- -----------------
  43. | mapping mode (WORD) | xExt (WORD) | yExt (WORD) | Normal metafile |
  44. --------------------- ------------- ------------- -----------------
  45. *****************************************************************************/
  46. FARINTERNAL UtGetHMFPICTFromMSDrawNativeStm
  47. (LPSTREAM pstm, DWORD dwSize, HANDLE FAR* lphdata)
  48. {
  49. HRESULT error;
  50. WORD mfp[3]; // mm, xExt, yExt
  51. HMETAFILE hMF = NULL;
  52. *lphdata = NULL;
  53. if (error = pstm->Read(mfp, sizeof(mfp), NULL))
  54. return error;
  55. dwSize -= sizeof(mfp);
  56. if (error = UtGetHMFFromMFStm(pstm, dwSize, FALSE, (void **)&hMF))
  57. return error;
  58. AssertSz(mfp[0] == MM_ANISOTROPIC, "invalid map mode in MsDraw native data");
  59. if (*lphdata = UtGetHMFPICT(hMF, TRUE, (int) mfp[1], (int) mfp[2]))
  60. return NOERROR;
  61. return ResultFromScode(E_OUTOFMEMORY);
  62. }
  63. FARINTERNAL UtPlaceableMFStmToMSDrawNativeStm
  64. (LPSTREAM pstmPMF, LPSTREAM pstmMSDraw)
  65. {
  66. DWORD dwSize; // size of metafile bits excluding the placeable MF header
  67. LONG xExt;
  68. LONG yExt;
  69. WORD wBuf[5]; // dwSize(DWORD), mm(int), xExt(int), yExt(int)
  70. HRESULT error;
  71. if (error = UtGetSizeAndExtentsFromPlaceableMFStm(pstmPMF, &dwSize,
  72. &xExt, &yExt))
  73. return error;
  74. *((DWORD FAR*) wBuf) = dwSize + 3*sizeof(WORD);
  75. wBuf[2] = MM_ANISOTROPIC;
  76. wBuf[3] = (int) xExt;
  77. wBuf[4] = (int) yExt;
  78. if (error = pstmMSDraw->Write(wBuf, sizeof(wBuf), 0))
  79. return error;
  80. ULARGE_INTEGER ularge_int;
  81. ULISet32(ularge_int, dwSize);
  82. if ((error = pstmPMF->CopyTo(pstmMSDraw, ularge_int,
  83. NULL, NULL)) == NOERROR)
  84. StSetSize(pstmMSDraw, 0, TRUE);
  85. return error;
  86. }
  87. FARINTERNAL UtDIBFileStmToPBrushNativeStm
  88. (LPSTREAM pstmDIBFile, LPSTREAM pstmPBrush)
  89. {
  90. BITMAPFILEHEADER bfh;
  91. HRESULT error;
  92. if (error = pstmDIBFile->Read(&bfh, sizeof(bfh), 0))
  93. return error;
  94. // seek to the begining of the stream
  95. LARGE_INTEGER large_int;
  96. LISet32( large_int, 0);
  97. if (error = pstmDIBFile->Seek(large_int, STREAM_SEEK_SET, 0))
  98. return error;
  99. if (error = pstmPBrush->Write(&(bfh.bfSize), sizeof(DWORD), 0))
  100. return error;
  101. ULARGE_INTEGER ularge_int;
  102. ULISet32(ularge_int, bfh.bfSize);
  103. if ((error = pstmDIBFile->CopyTo(pstmPBrush, ularge_int,
  104. NULL, NULL)) == NOERROR)
  105. StSetSize(pstmPBrush, 0, TRUE);
  106. return error;
  107. }
  108. FARINTERNAL UtContentsStmTo10NativeStm
  109. (LPSTORAGE pstg, REFCLSID rclsid, BOOL fDeleteSrcStm, UINT FAR* puiStatus)
  110. {
  111. CLIPFORMAT cf;
  112. LPOLESTR lpszUserType = NULL;
  113. HRESULT error;
  114. LPSTREAM pstmSrc = NULL;
  115. LPSTREAM pstmDst = NULL;
  116. *puiStatus = NULL;
  117. if (error = ReadFmtUserTypeStg(pstg, &cf, &lpszUserType))
  118. return error;
  119. if (! ((cf == CF_DIB && rclsid == CLSID_PBrush)
  120. || (cf == CF_METAFILEPICT && rclsid == CLSID_MSDraw))) {
  121. error = ResultFromScode(DV_E_CLIPFORMAT);
  122. goto errRtn;
  123. }
  124. if (error = pstg->OpenStream(OLE_CONTENTS_STREAM, NULL,
  125. (STGM_READ|STGM_SHARE_EXCLUSIVE),
  126. 0, &pstmSrc)) {
  127. *puiStatus |= CONVERT_NOSOURCE;
  128. // check whether OLE10_NATIVE_STREAM exists
  129. if (pstg->OpenStream(OLE10_NATIVE_STREAM, NULL,
  130. (STGM_READ|STGM_SHARE_EXCLUSIVE), 0, &pstmDst))
  131. *puiStatus |= CONVERT_NODESTINATION;
  132. else {
  133. pstmDst->Release();
  134. pstmDst = NULL;
  135. }
  136. goto errRtn;
  137. }
  138. if (error = OpenOrCreateStream(pstg, OLE10_NATIVE_STREAM, &pstmDst)) {
  139. *puiStatus |= CONVERT_NODESTINATION;
  140. goto errRtn;
  141. }
  142. if (cf == CF_METAFILEPICT)
  143. error = UtPlaceableMFStmToMSDrawNativeStm(pstmSrc, pstmDst);
  144. else
  145. error = UtDIBFileStmToPBrushNativeStm(pstmSrc, pstmDst);
  146. errRtn:
  147. if (pstmDst)
  148. pstmDst->Release();
  149. if (pstmSrc)
  150. pstmSrc->Release();
  151. if (error == NOERROR) {
  152. LPOLESTR lpszProgId = NULL;
  153. ProgIDFromCLSID(rclsid, &lpszProgId);
  154. error = WriteFmtUserTypeStg(pstg,
  155. (CLIPFORMAT) RegisterClipboardFormat(lpszProgId),
  156. lpszUserType);
  157. if (lpszProgId)
  158. delete lpszProgId;
  159. }
  160. if (error == NOERROR) {
  161. if (fDeleteSrcStm)
  162. pstg->DestroyElement(OLE_CONTENTS_STREAM);
  163. } else {
  164. pstg->DestroyElement(OLE10_NATIVE_STREAM);
  165. }
  166. if (lpszUserType)
  167. delete lpszUserType;
  168. return error;
  169. }
  170. FARINTERNAL Ut10NativeStmToContentsStm
  171. (LPSTORAGE pstg, REFCLSID rclsid, BOOL fDeleteSrcStm)
  172. {
  173. CLIPFORMAT cfOld;
  174. CLIPFORMAT cfNew;
  175. LPOLESTR lpszUserType = NULL;
  176. HRESULT error;
  177. LPSTREAM pstmSrc = NULL;
  178. LPSTREAM pstmDst = NULL;
  179. if (error = ReadFmtUserTypeStg(pstg, &cfOld, &lpszUserType))
  180. return error;
  181. if (rclsid == CLSID_StaticDib)
  182. cfNew = CF_DIB;
  183. else if (rclsid == CLSID_StaticMetafile)
  184. cfNew = CF_METAFILEPICT;
  185. else {
  186. AssertSz(FALSE, "Internal Error: this routine shouldn't have been called for this class");
  187. return ResultFromScode(E_FAIL);
  188. }
  189. if (cfOld == g_cfPBrush) {
  190. if (cfNew != CF_DIB) {
  191. error = ResultFromScode(DV_E_CLIPFORMAT);
  192. goto errRtn;
  193. }
  194. } else if (cfOld == g_cfMSDraw) {
  195. if (cfNew != CF_METAFILEPICT) {
  196. error = ResultFromScode(DV_E_CLIPFORMAT);
  197. goto errRtn;
  198. }
  199. } else {
  200. // Converted to static object from some class other than PBrush or
  201. // MSDraw. The data must be in a proper format in the CONTENTS
  202. // stream.
  203. return NOERROR;
  204. }
  205. if (error = pstg->OpenStream(OLE10_NATIVE_STREAM, NULL,
  206. (STGM_READ|STGM_SHARE_EXCLUSIVE),
  207. 0, &pstmSrc))
  208. goto errRtn;
  209. if (error = OpenOrCreateStream(pstg, OLE_CONTENTS_STREAM, &pstmDst))
  210. goto errRtn;
  211. DWORD dwSize;
  212. if (error = pstmSrc->Read(&dwSize, sizeof(DWORD), NULL))
  213. goto errRtn;
  214. if (cfOld == g_cfMSDraw) {
  215. WORD mfp[3]; // mm, xExt, yExt
  216. if (error = pstmSrc->Read(mfp, sizeof(mfp), NULL))
  217. goto errRtn;
  218. dwSize -= sizeof(mfp);
  219. error = UtMFStmToPlaceableMFStm(pstmSrc, dwSize,
  220. (LONG) mfp[1], (LONG) mfp[2], pstmDst);
  221. } else {
  222. // The PBrush native data format is DIB File format. So all we got to
  223. // do is CopyTo.
  224. ULARGE_INTEGER ularge_int;
  225. ULISet32(ularge_int, dwSize);
  226. if ((error = pstmSrc->CopyTo(pstmDst, ularge_int, NULL,
  227. NULL)) == NOERROR)
  228. StSetSize(pstmDst, 0, TRUE);
  229. }
  230. errRtn:
  231. if (pstmDst)
  232. pstmDst->Release();
  233. if (pstmSrc)
  234. pstmSrc->Release();
  235. if (error == NOERROR) {
  236. error = WriteFmtUserTypeStg(pstg, cfNew, lpszUserType);
  237. if (fDeleteSrcStm)
  238. pstg->DestroyElement(OLE10_NATIVE_STREAM);
  239. } else {
  240. pstg->DestroyElement(OLE_CONTENTS_STREAM);
  241. }
  242. if (lpszUserType)
  243. PubMemFree(lpszUserType);
  244. return error;
  245. }
  246. #endif