Leaked source code of windows server 2003
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.

417 lines
9.6 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1999 Microsoft Corporation
  4. *
  5. * Module Name:
  6. *
  7. * Object.cpp
  8. *
  9. * Abstract:
  10. *
  11. * Object factory for playing metafiles
  12. *
  13. * Created:
  14. *
  15. * 9/10/1999 DCurtis
  16. *
  17. \**************************************************************************/
  18. #include "precomp.hpp"
  19. #include "..\imaging\api\comutils.hpp"
  20. GpObject *
  21. GpObject::Factory(
  22. ObjectType type,
  23. const ObjectData * objectData,
  24. UINT size
  25. )
  26. {
  27. GpObject * object = NULL;
  28. ASSERT(ObjectTypeIsValid(type));
  29. switch (type)
  30. {
  31. case ObjectTypeBrush:
  32. if (size >= sizeof(ObjectTypeData))
  33. {
  34. GpBrushType brushType = (GpBrushType)(((ObjectTypeData *)objectData)->Type);
  35. switch(brushType)
  36. {
  37. case BrushTypeSolidColor:
  38. object = new GpSolidFill();
  39. break;
  40. case BrushTypeHatchFill:
  41. object = new GpHatch();
  42. break;
  43. case BrushTypeTextureFill:
  44. object = new GpTexture();
  45. break;
  46. /*
  47. // Removed for v1
  48. case BrushRectGrad:
  49. object = new GpRectGradient();
  50. break;
  51. */
  52. case BrushTypeLinearGradient:
  53. object = new GpLineGradient();
  54. break;
  55. /*
  56. // Removed for v1
  57. case BrushRadialGrad:
  58. object = new GpRadialGradient();
  59. break;
  60. case BrushTriangleGrad:
  61. object = new GpTriangleGradient();
  62. break;
  63. */
  64. case BrushTypePathGradient:
  65. object = new GpPathGradient();
  66. break;
  67. default:
  68. ASSERT(0); // unsupported brush type
  69. break;
  70. }
  71. }
  72. else
  73. {
  74. WARNING(("size is too small"));
  75. }
  76. break;
  77. case ObjectTypePen:
  78. object = new GpPen(GpColor(0,0,0), 1.0f);
  79. break;
  80. case ObjectTypePath:
  81. object = new GpPath();
  82. break;
  83. case ObjectTypeRegion:
  84. object = new GpRegion();
  85. break;
  86. case ObjectTypeImage:
  87. ASSERT(size >= sizeof(INT32));
  88. if (size >= sizeof(INT32))
  89. {
  90. GpImageType imageType = (GpImageType)(((ObjectTypeData *)objectData)->Type);
  91. switch(imageType)
  92. {
  93. case ImageTypeBitmap:
  94. object = new GpBitmap();
  95. break;
  96. case ImageTypeMetafile:
  97. object = new GpMetafile();
  98. break;
  99. default:
  100. ASSERT(0); // unsupported image type
  101. break;
  102. }
  103. }
  104. break;
  105. case ObjectTypeFont:
  106. object = new GpFont();
  107. break;
  108. case ObjectTypeStringFormat:
  109. object = new GpStringFormat();
  110. break;
  111. case ObjectTypeImageAttributes:
  112. object = new GpImageAttributes();
  113. break;
  114. case ObjectTypeCustomLineCap:
  115. if (size >= sizeof(ObjectTypeData))
  116. {
  117. CustomLineCapType capType = (CustomLineCapType)(((ObjectTypeData *)objectData)->Type);
  118. switch(capType)
  119. {
  120. case CustomLineCapTypeDefault:
  121. object = new GpCustomLineCap();
  122. break;
  123. case CustomLineCapTypeAdjustableArrow:
  124. object = new GpAdjustableArrowCap();
  125. break;
  126. default:
  127. ASSERT(0); // unsupported CustomLineCapType
  128. break;
  129. }
  130. }
  131. else
  132. {
  133. WARNING(("size is too small"));
  134. }
  135. break;
  136. default: // unsupported object type
  137. ASSERT(0);
  138. break;
  139. }
  140. return object;
  141. }
  142. class ExternalObjectData
  143. {
  144. public:
  145. UINT32 DataSize;
  146. UINT32 DataCRC;
  147. };
  148. UINT
  149. GpObject::GetExternalDataSize() const
  150. {
  151. UINT dataSize = this->GetDataSize();
  152. ASSERT(dataSize >= sizeof(ObjectData));
  153. ASSERT((dataSize & 0x03) == 0);
  154. return sizeof(ExternalObjectData) + dataSize;
  155. }
  156. GpStatus
  157. GpObject::GetExternalData(
  158. BYTE * dataBuffer,
  159. UINT & size
  160. )
  161. {
  162. ASSERT((dataBuffer != NULL) && (size > 0));
  163. if (size < (sizeof(ExternalObjectData) + sizeof(ObjectData)))
  164. {
  165. return InsufficientBuffer;
  166. }
  167. size -= sizeof(ExternalObjectData);
  168. BYTE * objectData = dataBuffer + sizeof(ExternalObjectData);
  169. UINT checkSum = 0;
  170. GpStatus status = this->GetData(objectData, size);
  171. if (status == Ok)
  172. {
  173. checkSum = Crc32(objectData, size, 0);
  174. }
  175. ((ExternalObjectData *)dataBuffer)->DataSize = size;
  176. ((ExternalObjectData *)dataBuffer)->DataCRC = checkSum;
  177. size += sizeof(ExternalObjectData);
  178. return status;
  179. }
  180. GpStatus
  181. GpObject::SetExternalData(
  182. const BYTE * dataBuffer,
  183. UINT size
  184. )
  185. {
  186. ASSERT((dataBuffer != NULL) && (size > 0));
  187. if (size < (sizeof(ExternalObjectData) + sizeof(ObjectData)))
  188. {
  189. return InsufficientBuffer;
  190. }
  191. size -= sizeof(ExternalObjectData);
  192. UINT dataSize = ((ExternalObjectData *)dataBuffer)->DataSize;
  193. if (size < dataSize)
  194. {
  195. return InsufficientBuffer;
  196. }
  197. const BYTE * objectData = dataBuffer + sizeof(ExternalObjectData);
  198. UINT checkSum = Crc32(objectData, dataSize, 0);
  199. if (((ExternalObjectData *)dataBuffer)->DataCRC != checkSum)
  200. {
  201. return InvalidParameter;
  202. }
  203. return this->SetData(objectData, size);
  204. }
  205. class ObjectBufferStream : public IUnknownBase<IStream>
  206. {
  207. public:
  208. ObjectBufferStream(BYTE * dataBuffer, UINT size)
  209. {
  210. ASSERT((dataBuffer != NULL) && (size > 0));
  211. DataBuffer = dataBuffer;
  212. BufferSize = size;
  213. Position = 0;
  214. Valid = TRUE;
  215. }
  216. ~ObjectBufferStream()
  217. {
  218. }
  219. BOOL IsValid() const
  220. {
  221. return Valid;
  222. }
  223. // how much data did we fill up?
  224. ULONG GetSize() const { return Position; }
  225. HRESULT STDMETHODCALLTYPE Write(
  226. VOID const HUGEP *pv,
  227. ULONG cb,
  228. ULONG *pcbWritten)
  229. {
  230. if (cb == 0)
  231. {
  232. if (pcbWritten != NULL)
  233. {
  234. *pcbWritten = cb;
  235. }
  236. return S_OK;
  237. }
  238. ASSERT (pv != NULL);
  239. if (Valid)
  240. {
  241. ULONG spaceLeft = BufferSize - Position;
  242. if (cb <= spaceLeft)
  243. {
  244. GpMemcpy(DataBuffer + Position, pv, cb);
  245. Position += cb;
  246. if (pcbWritten != NULL)
  247. {
  248. *pcbWritten = cb;
  249. }
  250. return S_OK;
  251. }
  252. // copy what we can
  253. if (spaceLeft > 0)
  254. {
  255. GpMemcpy(DataBuffer + Position, pv, spaceLeft);
  256. Position += spaceLeft;
  257. }
  258. if (pcbWritten != NULL)
  259. {
  260. *pcbWritten = spaceLeft;
  261. }
  262. Valid = FALSE; // tried to write past end of DataBuffer
  263. WARNING(("Tried to write past end of DataBuffer"));
  264. }
  265. return E_FAIL;
  266. }
  267. HRESULT STDMETHODCALLTYPE Read(
  268. VOID HUGEP *pv,
  269. ULONG cb,
  270. ULONG *pcbRead)
  271. {
  272. return E_NOTIMPL;
  273. }
  274. HRESULT STDMETHODCALLTYPE Seek(
  275. LARGE_INTEGER dlibMove,
  276. DWORD dwOrigin,
  277. ULARGE_INTEGER *plibNewPosition)
  278. {
  279. return E_NOTIMPL;
  280. }
  281. HRESULT STDMETHODCALLTYPE SetSize(
  282. ULARGE_INTEGER libNewSize)
  283. {
  284. return E_NOTIMPL;
  285. }
  286. HRESULT STDMETHODCALLTYPE CopyTo(
  287. IStream *pstm,
  288. ULARGE_INTEGER cb,
  289. ULARGE_INTEGER *pcbRead,
  290. ULARGE_INTEGER *pcbWritten)
  291. {
  292. return E_NOTIMPL;
  293. }
  294. HRESULT STDMETHODCALLTYPE Commit(
  295. DWORD grfCommitFlags)
  296. {
  297. return E_NOTIMPL;
  298. }
  299. HRESULT STDMETHODCALLTYPE Revert(VOID)
  300. {
  301. return E_NOTIMPL;
  302. }
  303. HRESULT STDMETHODCALLTYPE LockRegion(
  304. ULARGE_INTEGER libOffset,
  305. ULARGE_INTEGER cb,
  306. DWORD dwLockType)
  307. {
  308. return E_NOTIMPL;
  309. }
  310. HRESULT STDMETHODCALLTYPE UnlockRegion(
  311. ULARGE_INTEGER libOffset,
  312. ULARGE_INTEGER cb,
  313. DWORD dwLockType)
  314. {
  315. return E_NOTIMPL;
  316. }
  317. HRESULT STDMETHODCALLTYPE Stat(
  318. STATSTG *pstatstg,
  319. DWORD grfStatFlag)
  320. {
  321. return E_NOTIMPL;
  322. }
  323. HRESULT STDMETHODCALLTYPE Clone(
  324. IStream **ppstm)
  325. {
  326. return E_NOTIMPL;
  327. }
  328. private:
  329. BYTE * DataBuffer;
  330. ULONG BufferSize;
  331. ULONG Position;
  332. BOOL Valid;
  333. };
  334. GpStatus
  335. GpObject::GetData(
  336. BYTE * dataBuffer,
  337. UINT & size
  338. ) const
  339. {
  340. if ((dataBuffer != NULL) && (size > 0))
  341. {
  342. ObjectBufferStream objectBufferStream(dataBuffer, size);
  343. this->GetData(&objectBufferStream);
  344. size = objectBufferStream.GetSize();
  345. return objectBufferStream.IsValid() ? Ok : InsufficientBuffer;
  346. }
  347. size = 0;
  348. return InvalidParameter;
  349. }