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.

703 lines
22 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1999 Microsoft Corporation
  4. *
  5. * Module Name:
  6. *
  7. * MetaWmf.hpp
  8. *
  9. * Abstract:
  10. *
  11. * Metafile definitions for WMF and EMF playback
  12. *
  13. * Created:
  14. *
  15. * 1/6/2000 DCurtis
  16. *
  17. \**************************************************************************/
  18. #ifndef _METAWMF_HPP
  19. #define _METAWMF_HPP
  20. //#define GDIP_EXCEPTIONS 0
  21. #define GDIP_TRY __try {
  22. #define GDIP_CATCH } __except(EXCEPTION_EXECUTE_HANDLER) {
  23. #define GDIP_ENDCATCH }
  24. #define GDIP_RECORDBUFFER_SIZE 2048 // >= 1138 so pattern brushes work
  25. #define SIZEOF_METARECORDHEADER (sizeof(DWORD) + sizeof(WORD))
  26. #define NUM_STOCK_FONTS (DEFAULT_GUI_FONT - OEM_FIXED_FONT + 1)
  27. #define NUM_STOCK_RECOLOR_OBJS 7
  28. /*****************************************************************************
  29. Commenting.
  30. These interfaces allow comments to be added to a metafile DC which describe
  31. grouping and other information useful for decoding metafiles, the
  32. interfaces which take an MSODC have no effect if the DC is not a picture
  33. (PICT, WMF or EMF) DC.
  34. For PICT files there are two levels of structure, the public comment
  35. "kind" which is a globally defined comment and the "private" comment kind,
  36. which is used for application-specific comments. In a PICT the public
  37. comment kind is the kind argument to PicComment and the private kind is
  38. used if the public value is pictApplicationComment.
  39. In a WMF the signature indicates whether the comment is public or private,
  40. all comments look like the PICT private comment.
  41. In an EMF GdiComment() defines some "public" comments plus a format for
  42. "private" comments - see the Win32 API documentation.
  43. ******************************************************************* JohnBo **/
  44. // Definition of the comment codes used in the various metafile formats.
  45. const ULONG msosignaturePublic =0xFFFFFFFF; // WMF public signature.
  46. const ULONG msosignaturePPOld =0x5050FE54; // PowerPoint 2 signature
  47. const ULONG msosignaturePP =0x50504E54; // PowerPoint signature
  48. const ULONG msosignature =0x50504E54; // Office/Escher signature
  49. // The following enumeration defines the ukind values in the above structure,
  50. // note that these duplicate the PICT comment kinds for groups because in
  51. // a WMF (but *NOT* a PICT or EMF) and MSOMFCOMMENT structure must be used,
  52. // this enumeration contains all the valid kinds, including both the public
  53. // and private kinds, these may overlap because they are distinguished by
  54. // the "signature".
  55. typedef enum
  56. {
  57. // Public WMF comments - signature == msosignaturePublic.
  58. msocommentBeginGroup = 0x0000, // Public WMF begin group.
  59. msocommentEndGroup = 0x0001, // Public WMF end group.
  60. msocommentBeginHeader = 0x0002,
  61. msocommentEndHeader = 0x0003,
  62. msocommentCreator = 0x0004,
  63. msocommentWinVersion = 0x0005,
  64. // Private PICT and WMF comments - signature == msosignature.
  65. msocommentVersion = 0x0000,
  66. msocommentBFileBlock = 0x0001, // UNUSED
  67. msocommentBeginPicture = 0x0002,
  68. msocommentEndPicture = 0x0003,
  69. msocommentDevInfo = 0x0004,
  70. msocommentBeginHyperOpaque = 0x0005, // UNUSED
  71. msocommentEndHyperOpaque = 0x0006, // UNUSED
  72. msocommentBeginFade = 0x0007,
  73. msocommentEndFade = 0x0008,
  74. msocommentDitherDetect = 0x0009, // Not used now?
  75. // New values used in Office97.
  76. msocommentPictureDescription = 0x0101, // Description text.
  77. msocommentBeginGelEffect = 0x0102,
  78. msocommentEndGelEffect = 0x0103,
  79. msocommentBeginClipPath = 0x0104,
  80. msocommentEndClipPath = 0x0105,
  81. msocommentBeginSrcCopy = 0x0106,
  82. msocommentEndSrcCopy = 0x0107,
  83. // Reserved comments used internally by Mac PP4.
  84. msocommentPictUnmute = 0x7FFE,
  85. msocommentPictMute = 0x7FFF,
  86. // The following is a flag - what is it for?
  87. msocommentRegistered = 0x8000
  88. } MSOMFCOMMENTKIND;
  89. typedef struct
  90. {
  91. UINT Handle;
  92. COLORREF Color;
  93. BOOL Brush;
  94. }
  95. RecolorStockObject;
  96. extern RecolorStockObject RecolorStockObjectList[NUM_STOCK_RECOLOR_OBJS];
  97. enum GdipHdcType
  98. {
  99. UnknownHdc = 0x00000000,
  100. ScreenHdc = 0x00000001,
  101. BitmapHdc = 0x00000002,
  102. MetafileHdc = 0x00000004,
  103. PrinterHdc = 0x00000008,
  104. PostscriptHdc = 0x00010000,
  105. PostscriptPrinterHdc = PrinterHdc | PostscriptHdc,
  106. EmfHdc = 0x00100000 | MetafileHdc,
  107. WmfHdc = 0x00200000 | MetafileHdc,
  108. };
  109. enum MfFsmState
  110. {
  111. MfFsmStart,
  112. MfFsmPSData,
  113. MfFsmCreateBrushIndirect,
  114. MfFsmSelectBrush,
  115. MfFsmCreatePenIndirect,
  116. MfFsmSelectPen,
  117. MfFsmSetROP,
  118. };
  119. class MfEnumState
  120. {
  121. protected:
  122. GdipHdcType HdcType;
  123. HDC Hdc;
  124. INT SaveDcVal;
  125. INT SaveDcCount;
  126. INT NumObjects; // num objects in handle table
  127. INT SizeAllocedRecord;
  128. INT ModifiedRecordSize;
  129. INT BytesEnumerated;
  130. BOOL ExternalEnumeration;
  131. HPALETTE CurrentPalette;
  132. HFONT DefaultFont;
  133. HFONT StockFonts[NUM_STOCK_FONTS];
  134. HANDLETABLE * HandleTable;
  135. GpRecolor * Recolor;
  136. ColorAdjustType AdjustType;
  137. const BYTE * RecordData;
  138. UINT RecordDataSize;
  139. EmfPlusRecordType RecordType;
  140. InterpolationMode Interpolation;
  141. BOOL Is8Bpp;
  142. BOOL IsHalftonePalette;
  143. COLORREF BkColor;
  144. COLORREF TextColor;
  145. RECT DestRectDevice;
  146. BOOL RopUsed;
  147. DpContext * Context;
  148. union
  149. {
  150. const VOID * CurrentRecord;
  151. const METARECORD * CurrentWmfRecord;
  152. const ENHMETARECORD * CurrentEmfRecord;
  153. };
  154. union
  155. {
  156. VOID * ModifiedRecord;
  157. METARECORD * ModifiedWmfRecord;
  158. ENHMETARECORD * ModifiedEmfRecord;
  159. };
  160. union
  161. {
  162. VOID * AllocedRecord;
  163. METARECORD * AllocedWmfRecord;
  164. ENHMETARECORD * AllocedEmfRecord;
  165. };
  166. BYTE RecordBuffer[GDIP_RECORDBUFFER_SIZE];
  167. MfFsmState FsmState;
  168. BOOL GdiCentricMode;
  169. BOOL SoftekFilter;
  170. HGDIOBJ RecoloredStockHandle[NUM_STOCK_RECOLOR_OBJS];
  171. BOOL SrcCopyOnly;
  172. public:
  173. MfEnumState(
  174. HDC hdc,
  175. BOOL externalEnumeration,
  176. InterpolationMode interpolation,
  177. GpRecolor * recolor,
  178. ColorAdjustType adjustType,
  179. const RECT * dest,
  180. DpContext * context
  181. );
  182. ~MfEnumState();
  183. BOOL IsValid() { return (SaveDcVal != 0); }
  184. BOOL IsMetafile() { return ((HdcType & MetafileHdc) == MetafileHdc); }
  185. BOOL IsPostscript() { return ((HdcType & PostscriptHdc) == PostscriptHdc); }
  186. BOOL IsPrinter() { return ((HdcType & PrinterHdc) == PrinterHdc);}
  187. BOOL IsPostscriptPrinter(){ return ((HdcType & PostscriptPrinterHdc) == PostscriptPrinterHdc);}
  188. BOOL IsBitmap() { return ((HdcType & BitmapHdc) == BitmapHdc); }
  189. BOOL IsScreen() { return ((HdcType & ScreenHdc) == ScreenHdc); }
  190. BOOL GetRopUsed() { return RopUsed; }
  191. VOID ResetRopUsed() { RopUsed = FALSE; }
  192. VOID
  193. StartRecord(
  194. HDC hdc,
  195. HANDLETABLE * handleTable,
  196. INT numObjects,
  197. const VOID * currentRecord,
  198. EmfPlusRecordType recordType,
  199. UINT recordDataSize,
  200. const BYTE * recordData
  201. )
  202. {
  203. ASSERT(hdc != NULL);
  204. Hdc = hdc;
  205. ModifiedRecord = NULL;
  206. ModifiedRecordSize = 0;
  207. CurrentRecord = currentRecord;
  208. RecordType = recordType;
  209. RecordDataSize = recordDataSize;
  210. RecordData = recordData;
  211. BytesEnumerated += GetCurrentRecordSize();
  212. if ((handleTable != NULL) && (numObjects > 0))
  213. {
  214. HandleTable = handleTable;
  215. NumObjects = numObjects;
  216. }
  217. else
  218. {
  219. WARNING(("NULL handle table and/or no objects"));
  220. HandleTable = NULL;
  221. NumObjects = 0;
  222. }
  223. }
  224. virtual BOOL
  225. ProcessRecord(
  226. EmfPlusRecordType recordType,
  227. UINT recordDataSize,
  228. const BYTE * recordData
  229. ) = 0;
  230. virtual BOOL PlayRecord() = 0;
  231. VOID SaveHdc()
  232. {
  233. SaveDcCount--;
  234. this->PlayRecord();
  235. }
  236. virtual VOID RestoreHdc() = 0;
  237. VOID SelectPalette(INT objectIndex);
  238. protected:
  239. virtual INT GetCurrentRecordSize() const = 0;
  240. BOOL CreateRecordToModify(INT size = 0);
  241. COLORREF ModifyColor(
  242. COLORREF color,
  243. ColorAdjustType adjustType
  244. );
  245. INT
  246. GetModifiedDibSize(
  247. BITMAPINFOHEADER UNALIGNED * dibInfo,
  248. UINT numPalEntries,
  249. UINT dibBitsSize,
  250. UINT & usage
  251. );
  252. VOID
  253. ModifyDib(
  254. UINT usage,
  255. BITMAPINFOHEADER UNALIGNED * srcDibInfo,
  256. BYTE * srcBits,
  257. BITMAPINFOHEADER UNALIGNED * dstDibInfo,
  258. UINT numPalEntries,
  259. UINT srcDibBitsSize,
  260. ColorAdjustType adjustType
  261. );
  262. VOID
  263. Modify16BppDib(
  264. INT width,
  265. INT posHeight,
  266. BYTE * srcPixels,
  267. DWORD UNALIGNED * bitFields,
  268. BYTE * dstPixels,
  269. ColorAdjustType adjustType
  270. );
  271. VOID
  272. Modify24BppDib(
  273. INT width,
  274. INT posHeight,
  275. BYTE * srcPixels,
  276. DWORD UNALIGNED * bitFields,
  277. BYTE * dstPixels,
  278. ColorAdjustType adjustType
  279. );
  280. VOID
  281. Modify32BppDib(
  282. INT width,
  283. INT posHeight,
  284. BYTE * srcPixels,
  285. DWORD UNALIGNED * bitFields,
  286. BYTE * dstPixels,
  287. ColorAdjustType adjustType
  288. );
  289. VOID
  290. OutputDIB(
  291. HDC hdc,
  292. const RECTL * bounds,
  293. INT dstX,
  294. INT dstY,
  295. INT dstWidth,
  296. INT dstHeight,
  297. INT srcX,
  298. INT srcY,
  299. INT srcWidth,
  300. INT srcHeight,
  301. BITMAPINFOHEADER UNALIGNED * dibInfo,
  302. BYTE * bits, // if NULL, this is a packed DIB
  303. UINT usage,
  304. DWORD rop,
  305. BOOL isWmfDib
  306. );
  307. virtual BOOL CreateAndPlayOutputDIBRecord(
  308. HDC hdc,
  309. const RECTL * bounds,
  310. INT dstX,
  311. INT dstY,
  312. INT dstWidth,
  313. INT dstHeight,
  314. INT srcX,
  315. INT srcY,
  316. INT srcWidth,
  317. INT srcHeight,
  318. BITMAPINFOHEADER UNALIGNED * dibInfo,
  319. BYTE * bits, // if NULL, this is a packed DIB
  320. UINT usage,
  321. DWORD rop
  322. )=0;
  323. virtual BOOL CreateAndPlayCommentRecord()
  324. {
  325. return TRUE;
  326. }
  327. virtual VOID IntersectDestRect()=0;
  328. };
  329. class WmfEnumState : public MfEnumState
  330. {
  331. public:
  332. BOOL IgnorePostscript;
  333. protected:
  334. INT MetafileSize;
  335. HPEN HpenSave;
  336. HBRUSH HbrushSave;
  337. HPALETTE HpaletteSave;
  338. HFONT HfontSave;
  339. HBITMAP HbitmapSave;
  340. HRGN HregionSave;
  341. BOOL FirstViewportOrg;
  342. BOOL FirstViewportExt;
  343. GpMatrix ViewportXForm;
  344. POINT ImgViewportOrg;
  345. SIZE ImgViewportExt;
  346. POINT DstViewportOrg;
  347. SIZE DstViewportExt;
  348. BOOL IsFirstRecord;
  349. public:
  350. WmfEnumState(
  351. HDC hdc,
  352. HMETAFILE hWmf,
  353. BOOL externalEnumeration,
  354. InterpolationMode interpolation,
  355. const RECT * dstRect,
  356. const RECT * deviceRect,
  357. DpContext * context,
  358. GpRecolor * recolor = NULL,
  359. ColorAdjustType adjustType = ColorAdjustTypeDefault
  360. );
  361. ~WmfEnumState();
  362. virtual BOOL
  363. ProcessRecord(
  364. EmfPlusRecordType recordType,
  365. UINT recordDataSize,
  366. const BYTE * recordData
  367. );
  368. virtual BOOL PlayRecord();
  369. virtual VOID RestoreHdc();
  370. VOID EndRecord();
  371. VOID SetBkColor()
  372. {
  373. BkColor = *((COLORREF UNALIGNED *)&(((WORD UNALIGNED *)RecordData)[0]));
  374. ModifyRecordColor(0, ColorAdjustTypeBrush);
  375. this->PlayRecord();
  376. }
  377. VOID SetTextColor()
  378. {
  379. TextColor = *((COLORREF UNALIGNED *)&(((WORD UNALIGNED *)RecordData)[0]));
  380. ModifyRecordColor(0, ColorAdjustTypeText);
  381. this->PlayRecord();
  382. }
  383. VOID FloodFill()
  384. {
  385. ModifyRecordColor(0, ColorAdjustTypeBrush);
  386. this->PlayRecord();
  387. }
  388. VOID ExtFloodFill()
  389. {
  390. ModifyRecordColor(1, ColorAdjustTypeBrush);
  391. this->PlayRecord();
  392. }
  393. VOID SetPixel()
  394. {
  395. ModifyRecordColor(0, ColorAdjustTypePen);
  396. this->PlayRecord();
  397. }
  398. VOID DibCreatePatternBrush();
  399. VOID CreatePatternBrush();
  400. VOID CreatePenIndirect();
  401. VOID CreateBrushIndirect();
  402. VOID BitBlt();
  403. VOID StretchBlt()
  404. {
  405. this->BitBlt();
  406. }
  407. VOID Escape();
  408. VOID SetDIBitsToDevice();
  409. VOID PolyPolygon();
  410. VOID DIBBitBlt();
  411. VOID DIBStretchBlt()
  412. {
  413. this->DIBBitBlt();
  414. }
  415. VOID StretchDIBits();
  416. VOID SetViewportOrg();
  417. VOID SetViewportExt();
  418. VOID Rectangle();
  419. VOID CreateFontIndirect();
  420. VOID SelectObject();
  421. VOID CreateRegion();
  422. VOID SetROP2();
  423. protected:
  424. virtual INT GetCurrentRecordSize() const { return RecordDataSize + SIZEOF_METARECORDHEADER; }
  425. BOOL CreateCopyOfCurrentRecord();
  426. VOID ModifyRecordColor(
  427. INT paramIndex,
  428. ColorAdjustType adjustType
  429. );
  430. VOID MakeSolidBlackBrush();
  431. VOID CalculateViewportMatrix();
  432. virtual BOOL CreateAndPlayOutputDIBRecord(
  433. HDC hdc,
  434. const RECTL * bounds,
  435. INT dstX,
  436. INT dstY,
  437. INT dstWidth,
  438. INT dstHeight,
  439. INT srcX,
  440. INT srcY,
  441. INT srcWidth,
  442. INT srcHeight,
  443. BITMAPINFOHEADER UNALIGNED * dibInfo,
  444. BYTE * bits, // if NULL, this is a packed DIB
  445. UINT usage,
  446. DWORD rop
  447. );
  448. virtual VOID IntersectDestRect();
  449. };
  450. class EmfEnumState : public MfEnumState
  451. {
  452. protected:
  453. HRGN ClipRgn;
  454. POINT BrushOrg;
  455. HPALETTE Palette;
  456. public:
  457. EmfEnumState(
  458. HDC hdc,
  459. HENHMETAFILE hEmf,
  460. const RECT * dest,
  461. const RECT * deviceRect,
  462. BOOL externalEnumeration,
  463. InterpolationMode interpolation,
  464. DpContext * context,
  465. GpRecolor * recolor = NULL,
  466. ColorAdjustType adjustType = ColorAdjustTypeDefault
  467. );
  468. ~EmfEnumState()
  469. {
  470. GpFree(AllocedRecord);
  471. if (IsMetafile())
  472. {
  473. // Bug 106406 from Office: Missing RestoreDC in EMF
  474. // Account for unbalanced SaveDC/RestoreDC pairs and
  475. // restore to the saveDC state
  476. ::RestoreDC(Hdc, SaveDcCount - 1);
  477. }
  478. else
  479. {
  480. ::RestoreDC(Hdc, SaveDcVal);
  481. }
  482. }
  483. virtual BOOL
  484. ProcessRecord(
  485. EmfPlusRecordType recordType,
  486. UINT recordDataSize,
  487. const BYTE * recordData
  488. );
  489. // returns a pointer to the current record, but the header may
  490. // not actually be there -- just the data of the record.
  491. const ENHMETARECORD * GetPartialRecord()
  492. {
  493. if (CurrentEmfRecord != NULL)
  494. {
  495. return CurrentEmfRecord;
  496. }
  497. ASSERT(RecordData != NULL);
  498. return (const ENHMETARECORD *)(((const BYTE *)RecordData) - sizeof(EMR));
  499. }
  500. virtual BOOL PlayRecord();
  501. virtual VOID RestoreHdc();
  502. VOID Header();
  503. VOID SelectPalette(INT objectIndex);
  504. VOID SetPixelV()
  505. {
  506. ModifyRecordColor(2, ColorAdjustTypePen);
  507. this->PlayRecord();
  508. }
  509. VOID SetTextColor()
  510. {
  511. TextColor = ((COLORREF *)RecordData)[0];
  512. ModifyRecordColor(0, ColorAdjustTypeText);
  513. this->PlayRecord();
  514. }
  515. VOID SetBkColor()
  516. {
  517. BkColor = ((COLORREF *)RecordData)[0];
  518. ModifyRecordColor(0, ColorAdjustTypeBrush);
  519. this->PlayRecord();
  520. }
  521. VOID CreatePen();
  522. VOID CreateBrushIndirect();
  523. VOID ExtFloodFill()
  524. {
  525. ModifyRecordColor(2, ColorAdjustTypeBrush);
  526. this->PlayRecord();
  527. }
  528. VOID GdiComment();
  529. VOID BitBlt();
  530. VOID StretchBlt();
  531. VOID SetDIBitsToDevice();
  532. VOID StretchDIBits();
  533. VOID CreateDibPatternBrushPt();
  534. VOID ExtCreatePen();
  535. VOID MaskBlt()
  536. {
  537. // !!! to do
  538. ResetRecordBounds();
  539. this->PlayRecord();
  540. }
  541. VOID PlgBlt()
  542. {
  543. // !!! to do
  544. ResetRecordBounds();
  545. this->PlayRecord();
  546. }
  547. VOID GradientFill()
  548. {
  549. // !!! to do
  550. this->PlayRecord();
  551. }
  552. VOID TransparentBlt()
  553. {
  554. // !!! to do
  555. ResetRecordBounds();
  556. this->PlayRecord();
  557. }
  558. VOID AlphaBlend()
  559. {
  560. // !!! to do
  561. ResetRecordBounds();
  562. this->PlayRecord();
  563. }
  564. VOID ExtEscape();
  565. VOID ExtCreateFontIndirect();
  566. VOID SelectObject();
  567. VOID SetROP2();
  568. VOID ExtTextOutW();
  569. VOID Rectangle();
  570. protected:
  571. virtual INT GetCurrentRecordSize() const { return RecordDataSize + sizeof(EMR); }
  572. BOOL CreateCopyOfCurrentRecord();
  573. VOID ModifyRecordColor(
  574. INT paramIndex,
  575. ColorAdjustType adjustType
  576. );
  577. BOOL ValidObjectIndex(INT objectIndex)
  578. {
  579. return ((objectIndex > 0) && (objectIndex < NumObjects));
  580. }
  581. BITMAPINFOHEADER *
  582. CreateModifiedDib(
  583. BITMAPINFOHEADER * srcDibInfo,
  584. BYTE * srcBits,
  585. UINT & usage,
  586. DWORD rop
  587. );
  588. virtual BOOL CreateAndPlayOutputDIBRecord(
  589. HDC hdc,
  590. const RECTL * bounds,
  591. INT dstX,
  592. INT dstY,
  593. INT dstWidth,
  594. INT dstHeight,
  595. INT srcX,
  596. INT srcY,
  597. INT srcWidth,
  598. INT srcHeight,
  599. BITMAPINFOHEADER UNALIGNED * dibInfo,
  600. BYTE * bits, // if NULL, this is a packed DIB
  601. UINT usage,
  602. DWORD rop
  603. );
  604. virtual VOID IntersectDestRect();
  605. VOID ResetRecordBounds();
  606. virtual BOOL CreateAndPlayCommentRecord()
  607. {
  608. // This will create an Empty comment record and play it through GDI
  609. // This is necessary to invalidate the Transform cache that Win9x keeps
  610. // while playing metafiles. If we need to query the current transform
  611. // this makes sure that the result is the current one and not the
  612. // previously cached transform
  613. // Allocate a comment buffer that has 1 DWORD in the Data field.
  614. BYTE buffer[(sizeof(EMRGDICOMMENT)+3) & ~3];
  615. EMRGDICOMMENT* comment = (EMRGDICOMMENT*) buffer;
  616. comment->emr.iType = EMR_GDICOMMENT;
  617. comment->emr.nSize = (sizeof(EMRGDICOMMENT)+3) & ~3;
  618. comment->cbData = 4;
  619. *(DWORD*)(comment->Data) = 0;
  620. return PlayEnhMetaFileRecord(Hdc, HandleTable, (ENHMETARECORD*)comment, NumObjects);
  621. }
  622. };
  623. BOOL
  624. GetDibNumPalEntries(
  625. BOOL isWmfDib,
  626. UINT biSize,
  627. UINT biBitCount,
  628. UINT biCompression,
  629. UINT biClrUsed,
  630. UINT * numPalEntries
  631. );
  632. UINT
  633. GetDibBitsSize(
  634. BITMAPINFOHEADER UNALIGNED * dibInfo
  635. );
  636. inline static BOOL
  637. IsSourceInRop3(
  638. DWORD rop3
  639. )
  640. {
  641. return (rop3 & 0xCCCC0000) != ((rop3 << 2) & 0xCCCC0000);
  642. }
  643. #endif // !_METAWMF_HPP