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.

1146 lines
29 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: DRAW.C
  3. *
  4. * PURPOSE: Contains all the drawing related routines
  5. *
  6. * Created: March 1991
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * (03/21/91) Srinik Original
  12. * (03/22/91) Srinik Added support for drawing metafile in a metafile
  13. * curts created portable version for WIN16/32
  14. *
  15. \***************************************************************************/
  16. #include <windows.h>
  17. #include "dll.h"
  18. #include "pict.h"
  19. #define RECORD_COUNT 16
  20. int INTERNAL PaletteSize (int);
  21. HANDLE INTERNAL DibMakeLogPalette(LPSTR, UINT, LPLOGPALETTE FAR *);
  22. OLESTATUS FARINTERNAL wDibDraw (HANDLE, HDC, LPRECT, LPRECT, HDC, BOOL);
  23. OLESTATUS INTERNAL wDrawBitmap (LPOBJECT_BM, HDC, HDC, LPRECT);
  24. OLESTATUS INTERNAL wDrawBitmapUsingDib (LPOBJECT_BM, HDC, HDC, HDC, LPRECT, LPRECT);
  25. void SetPictOrg (LPOBJECT_MF, HDC, int, int, BOOL);
  26. void SetPictExt (LPOBJECT_MF, HDC, int, int);
  27. void ScalePictExt (LPOBJECT_MF, HDC, int, int, int, int);
  28. void ScaleRectExt (LPOBJECT_MF, HDC, int, int, int, int);
  29. void CleanStack(LPOBJECT_MF, HANDLE);
  30. BOOL PopDc (LPOBJECT_MF);
  31. BOOL PushDc (LPOBJECT_MF);
  32. #ifdef META_DEBUG
  33. void PutMetaFuncName (UINT);
  34. #endif
  35. OLESTATUS FARINTERNAL BmDraw (
  36. LPOLEOBJECT lpoleobj,
  37. HDC hdc,
  38. OLE_CONST RECT FAR* lprc,
  39. OLE_CONST RECT FAR* lpWrc,
  40. HDC hdcTarget
  41. ){
  42. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  43. int iScreenDevCaps;
  44. HDC hMemDC, hScreenDC;
  45. OLESTATUS ret = OLE_OK;
  46. if (!lpobj->hBitmap)
  47. return OLE_ERROR_BLANK;
  48. if (!(hScreenDC = GetDC (NULL))){
  49. return OLE_ERROR_MEMORY;
  50. }
  51. iScreenDevCaps = GetDeviceCaps (hScreenDC, TECHNOLOGY);
  52. if (!OleIsDcMeta (hdc)
  53. && (iScreenDevCaps != GetDeviceCaps (hdc, TECHNOLOGY))) {
  54. ret = wDrawBitmapUsingDib (lpobj, hdc, hScreenDC,
  55. hdcTarget, (LPRECT)lprc, (LPRECT)lpWrc);
  56. }
  57. else {
  58. hMemDC = CreateCompatibleDC (hdc);
  59. if (hMemDC) {
  60. ret = wDrawBitmap (lpobj, hdc, hMemDC, (LPRECT)lprc);
  61. DeleteDC (hMemDC);
  62. } else {
  63. ret = OLE_ERROR_MEMORY;
  64. }
  65. }
  66. ReleaseDC (NULL, hScreenDC);
  67. return ret;
  68. }
  69. OLESTATUS INTERNAL wDrawBitmap (
  70. LPOBJECT_BM lpobj,
  71. HDC hdc,
  72. HDC hMemDC,
  73. LPRECT lprc
  74. ){
  75. HBITMAP hOldBitmap;
  76. OLESTATUS ret = OLE_OK;
  77. if (!hMemDC)
  78. return OLE_ERROR_MEMORY;
  79. if (!(hOldBitmap = SelectObject(hMemDC, lpobj->hBitmap)))
  80. return OLE_ERROR_DRAW;
  81. if (!StretchBlt(hdc,
  82. lprc->left, lprc->top,
  83. (lprc->right - lprc->left), (lprc->bottom - lprc->top),
  84. hMemDC, 0, 0, lpobj->xSize, lpobj->ySize, SRCCOPY)) {
  85. ret = OLE_ERROR_DRAW;
  86. }
  87. SelectObject (hMemDC, hOldBitmap);
  88. return ret;
  89. }
  90. OLESTATUS INTERNAL wDrawBitmapUsingDib (
  91. LPOBJECT_BM lpobj,
  92. HDC hdc,
  93. HDC hScreenDC,
  94. HDC hTargetDC,
  95. LPRECT lprc,
  96. LPRECT lpWrc
  97. ){
  98. BITMAP bm;
  99. LPBITMAPINFOHEADER lpBmi;
  100. HANDLE hBmi, hDib = NULL;
  101. UINT wBmiSize;
  102. OLESTATUS retVal = OLE_ERROR_MEMORY;
  103. if (!GetObject(lpobj->hBitmap, sizeof(BITMAP), (LPSTR) &bm))
  104. return OLE_ERROR_HANDLE;
  105. wBmiSize = sizeof(BITMAPINFOHEADER)
  106. + PaletteSize(bm.bmPlanes * bm.bmBitsPixel);
  107. if (!(hBmi = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT, wBmiSize)))
  108. return OLE_ERROR_MEMORY;
  109. if (!(lpBmi = (LPBITMAPINFOHEADER) GlobalLock (hBmi))) {
  110. GlobalFree (hBmi);
  111. return OLE_ERROR_MEMORY;
  112. }
  113. GlobalUnlock (hBmi);
  114. lpBmi->biSize = (LONG) sizeof(BITMAPINFOHEADER);
  115. lpBmi->biWidth = (LONG) bm.bmWidth;
  116. lpBmi->biHeight = (LONG) bm.bmHeight;
  117. lpBmi->biPlanes = 1;
  118. lpBmi->biBitCount = bm.bmPlanes * bm.bmBitsPixel;
  119. lpBmi->biCompression = BI_RGB;
  120. lpBmi->biSizeImage = 0L;
  121. lpBmi->biXPelsPerMeter = 0L;
  122. lpBmi->biYPelsPerMeter = 0L;
  123. lpBmi->biClrUsed = 0L;
  124. lpBmi->biClrImportant = 0L;
  125. // Call GetDIBits with a NULL lpBits parm, so that it will calculate
  126. // the biSizeImage field for us
  127. if (!GetDIBits(hScreenDC, lpobj->hBitmap, 0, bm.bmHeight, NULL,
  128. (LPBITMAPINFO)lpBmi, DIB_RGB_COLORS))
  129. return OLE_ERROR_HANDLE;
  130. // Realloc the buffer to provide space for the bits
  131. if (!(hDib = GlobalReAlloc (hBmi, (wBmiSize + lpBmi->biSizeImage),
  132. GMEM_MOVEABLE))) {
  133. GlobalFree (hBmi);
  134. return OLE_ERROR_MEMORY;
  135. }
  136. // If reallocation gave a new handle then lock that handle and get the
  137. // long pointer to it.
  138. if (hDib != hBmi) {
  139. if (!(lpBmi = (LPBITMAPINFOHEADER) GlobalLock (hDib)))
  140. goto errRtn;
  141. GlobalUnlock (hDib);
  142. }
  143. // Call GetDIBits with a NON-NULL lpBits parm, and get the actual bits
  144. if (!GetDIBits(hScreenDC, lpobj->hBitmap, 0, (WORD) lpBmi->biHeight,
  145. ((LPSTR)lpBmi)+wBmiSize,
  146. (LPBITMAPINFO) lpBmi,
  147. DIB_RGB_COLORS)) {
  148. retVal = OLE_ERROR_HANDLE;
  149. goto errRtn;
  150. }
  151. retVal = wDibDraw (hDib, hdc, lprc, lpWrc, hTargetDC, FALSE);
  152. errRtn:
  153. if (hDib)
  154. GlobalFree (hDib);
  155. return retVal;
  156. }
  157. OLESTATUS FARINTERNAL DibDraw (
  158. LPOLEOBJECT lpoleobj,
  159. HDC hdc,
  160. OLE_CONST RECT FAR* lprc,
  161. OLE_CONST RECT FAR* lpWrc,
  162. HDC hdcTarget
  163. ){
  164. LPOBJECT_DIB lpobj = (LPOBJECT_DIB)lpoleobj;
  165. return wDibDraw (lpobj->hDIB, hdc, (LPRECT)lprc, (LPRECT)lpWrc, hdcTarget, FALSE);
  166. }
  167. OLESTATUS FARINTERNAL wDibDraw (
  168. HANDLE hData,
  169. HDC hdc,
  170. LPRECT lprc,
  171. LPRECT lpWrc,
  172. HDC hdcTarget,
  173. BOOL bPbrushData
  174. ){
  175. // !!! current implementation is not using hdcTarget
  176. OLESTATUS ret = OLE_ERROR_DRAW;
  177. LPSTR lpData;
  178. HANDLE hPalette = NULL;
  179. HPALETTE hLogPalette = NULL, hOldPalette = NULL;
  180. LPLOGPALETTE lpLogPalette;
  181. UINT wPalSize;
  182. int iOffBits;
  183. HANDLE hbminfo = NULL;
  184. LPBITMAPINFO lpbminfo;
  185. UNREFERENCED_PARAMETER(lpWrc);
  186. UNREFERENCED_PARAMETER(hdcTarget);
  187. if (!hData)
  188. return OLE_ERROR_BLANK;
  189. if (!(lpData = GlobalLock (hData)))
  190. return OLE_ERROR_MEMORY;
  191. if (bPbrushData)
  192. {
  193. BITMAPINFO UNALIGNED * lpbminfoTmp;
  194. DWORD dwSize;
  195. lpData += sizeof(BITMAPFILEHEADER);
  196. lpbminfoTmp = (BITMAPINFO UNALIGNED *)lpData;
  197. dwSize = sizeof(BITMAPINFOHEADER) + PaletteSize (lpbminfoTmp->bmiHeader.biBitCount);
  198. if (!(hbminfo = GlobalAlloc(GHND, dwSize)) )
  199. return OLE_ERROR_MEMORY;
  200. if (!(lpbminfo = (LPBITMAPINFO)GlobalLock(hbminfo)) )
  201. {
  202. ret = OLE_ERROR_MEMORY;
  203. goto end;
  204. }
  205. memcpy( (LPSTR)lpbminfo, lpData, dwSize );
  206. }
  207. else
  208. lpbminfo = (LPBITMAPINFO)lpData;
  209. wPalSize = PaletteSize (lpbminfo->bmiHeader.biBitCount);
  210. iOffBits = sizeof(BITMAPINFOHEADER) + wPalSize;
  211. // if color palette exits do the following
  212. if (wPalSize) {
  213. if (!(hLogPalette = DibMakeLogPalette(lpData+sizeof(BITMAPINFOHEADER),
  214. wPalSize, &lpLogPalette))) {
  215. ret = OLE_ERROR_MEMORY;
  216. goto end;
  217. }
  218. if (!(hPalette = CreatePalette (lpLogPalette)))
  219. goto end;
  220. // select as a background palette
  221. if (!(hOldPalette = SelectPalette (hdc, hPalette, TRUE)))
  222. goto end;
  223. RealizePalette(hdc);
  224. }
  225. if (!StretchDIBits(hdc,
  226. lprc->left, lprc->top,
  227. (lprc->right - lprc->left), (lprc->bottom - lprc->top),
  228. 0, 0,
  229. (UINT) lpbminfo->bmiHeader.biWidth,
  230. (UINT) lpbminfo->bmiHeader.biHeight,
  231. lpData + iOffBits,
  232. lpbminfo,
  233. DIB_RGB_COLORS,
  234. SRCCOPY)) {
  235. ret = OLE_ERROR_DRAW;
  236. }
  237. else
  238. ret = OLE_OK;
  239. end:
  240. // if color palette exists do the following
  241. if (wPalSize) {
  242. hOldPalette = (OleIsDcMeta (hdc) ? GetStockObject(DEFAULT_PALETTE)
  243. : hOldPalette);
  244. if (hOldPalette) {
  245. // select as a background palette
  246. SelectPalette (hdc, hOldPalette, TRUE);
  247. RealizePalette (hdc);
  248. }
  249. if (hPalette)
  250. DeleteObject (hPalette);
  251. if (hLogPalette)
  252. GlobalFree (hLogPalette);
  253. }
  254. GlobalUnlock (hData);
  255. if (hbminfo)
  256. {
  257. GlobalUnlock(hbminfo);
  258. GlobalFree(hbminfo);
  259. }
  260. return ret;
  261. }
  262. HANDLE INTERNAL DibMakeLogPalette (
  263. LPSTR lpColorData,
  264. UINT wDataSize,
  265. LPLOGPALETTE FAR * lplpLogPalette
  266. ){
  267. HANDLE hLogPalette=NULL;
  268. LPLOGPALETTE lpLogPalette;
  269. DWORD dwLogPalSize = wDataSize + 2 * sizeof(UINT);
  270. LPPALETTEENTRY lpPE;
  271. RGBQUAD FAR * lpQuad;
  272. if (!(hLogPalette = GlobalAlloc(GMEM_MOVEABLE,dwLogPalSize)))
  273. return NULL;
  274. if (!(lpLogPalette = (LPLOGPALETTE) GlobalLock (hLogPalette))) {
  275. GlobalFree (hLogPalette);
  276. return NULL;
  277. }
  278. GlobalUnlock (hLogPalette);
  279. *lplpLogPalette = lpLogPalette;
  280. lpLogPalette->palVersion = 0x300;
  281. lpLogPalette->palNumEntries = (WORD)(wDataSize / sizeof(PALETTEENTRY));
  282. /* now convert RGBQUAD to PALETTEENTRY as we copy color info */
  283. for (lpQuad = (RGBQUAD far *)lpColorData,
  284. lpPE = (LPPALETTEENTRY)lpLogPalette->palPalEntry,
  285. wDataSize /= sizeof(RGBQUAD);
  286. wDataSize--;
  287. ++lpQuad,++lpPE) {
  288. lpPE->peFlags=0;
  289. lpPE->peRed = lpQuad->rgbRed;
  290. lpPE->peBlue = lpQuad->rgbBlue;
  291. lpPE->peGreen = lpQuad->rgbGreen;
  292. }
  293. return hLogPalette;
  294. }
  295. int INTERNAL PaletteSize (int iBitCount)
  296. {
  297. switch (iBitCount) {
  298. case 1:
  299. return (2*sizeof(RGBQUAD));
  300. case 4:
  301. return (16*sizeof(RGBQUAD));
  302. case 8:
  303. return (256*sizeof(RGBQUAD));
  304. default:
  305. return 0; /* A 24 bitcount DIB has no color table */
  306. }
  307. }
  308. OLESTATUS FARINTERNAL GenDraw (
  309. LPOLEOBJECT lpoleobj,
  310. HDC hdc,
  311. OLE_CONST RECT FAR* lprc,
  312. OLE_CONST RECT FAR* lpWrc,
  313. HDC hdcTarget
  314. ){
  315. LPOBJECT_GEN lpobj = (LPOBJECT_GEN) lpoleobj;
  316. UNREFERENCED_PARAMETER(hdc);
  317. UNREFERENCED_PARAMETER(lprc);
  318. UNREFERENCED_PARAMETER(lpWrc);
  319. UNREFERENCED_PARAMETER(hdcTarget);
  320. return OLE_ERROR_GENERIC;
  321. }
  322. ////////////////////////////////////////////////////////////////////////////
  323. // METAFILE draw routines
  324. ////////////////////////////////////////////////////////////////////////////
  325. OLESTATUS FARINTERNAL MfDraw (
  326. LPOLEOBJECT lpoleobj,
  327. HDC hdc,
  328. OLE_CONST RECT FAR* lprc,
  329. OLE_CONST RECT FAR* lpWrc,
  330. HDC hdcTarget
  331. ){
  332. LPOBJECT_MF lpobj = (LPOBJECT_MF) lpoleobj;
  333. HANDLE hInfo;
  334. int iOldDc;
  335. RECT rect;
  336. LPRECT lpRrc = (LPRECT) &rect;
  337. UNREFERENCED_PARAMETER(hdcTarget);
  338. rect.left = lprc->left;
  339. rect.right = lprc->right;
  340. rect.top = lprc->top;
  341. rect.bottom = lprc->bottom;
  342. if (!lpobj->mfp.hMF)
  343. return OLE_ERROR_BLANK;
  344. lpobj->nRecord = RECORD_COUNT;
  345. lpobj->fMetaDC = OleIsDcMeta (hdc);
  346. if (!(iOldDc = SaveDC (hdc)))
  347. return OLE_ERROR_MEMORY;
  348. IntersectClipRect (hdc, lpRrc->left, lpRrc->top,
  349. lpRrc->right, lpRrc->bottom);
  350. if (!lpobj->fMetaDC) {
  351. LPtoDP (hdc, (LPPOINT) lpRrc, 2);
  352. SetMapMode (hdc, MM_ANISOTROPIC);
  353. MSetViewportOrg (hdc, lpRrc->left, lpRrc->top);
  354. MSetViewportExt (hdc, lpRrc->right - lpRrc->left,
  355. lpRrc->bottom - lpRrc->top);
  356. }
  357. else {
  358. iOldDc = -1;
  359. if (!lpWrc) {
  360. #ifdef FIREWALLS
  361. ASSERT(0, "Pointer to rect is null")
  362. #endif
  363. return OLE_ERROR_DRAW;
  364. }
  365. if (!(hInfo = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
  366. sizeof(METAINFO))))
  367. return OLE_ERROR_MEMORY;
  368. if (!(lpobj->pMetaInfo = (PMETAINFO) LocalLock (hInfo))) {
  369. LocalFree (hInfo);
  370. return OLE_ERROR_MEMORY;
  371. }
  372. LocalUnlock (hInfo);
  373. lpobj->pCurMdc = (PMETADC) (lpobj->pMetaInfo);
  374. lpobj->pMetaInfo->xwo = lpWrc->left;
  375. lpobj->pMetaInfo->ywo = lpWrc->top;
  376. lpobj->pMetaInfo->xwe = lpWrc->right;
  377. lpobj->pMetaInfo->ywe = lpWrc->bottom;
  378. lpobj->pMetaInfo->xro = lpRrc->left - lpWrc->left;
  379. lpobj->pMetaInfo->yro = lpRrc->top - lpWrc->top;
  380. lpobj->pCurMdc->xre = lpRrc->right - lpRrc->left;
  381. lpobj->pCurMdc->yre = lpRrc->bottom - lpRrc->top;
  382. }
  383. lpobj->error = OLE_OK;
  384. MfInterruptiblePaint(lpobj, hdc);
  385. if (lpobj->fMetaDC)
  386. CleanStack (lpobj, hInfo);
  387. RestoreDC (hdc, iOldDc);
  388. return lpobj->error;
  389. }
  390. void INTERNAL MfInterruptiblePaint (
  391. LPOBJECT_MF lpobj,
  392. HDC hdc
  393. ){
  394. EnumMetaFile (hdc,lpobj->mfp.hMF, (MFENUMPROC)MfCallbackFunc, (LPARAM)lpobj);
  395. }
  396. BOOL APIENTRY MfCallbackFunc (
  397. HDC hdc,
  398. LPHANDLETABLE lpHTable,
  399. LPMETARECORD lpMFR,
  400. int nObj,
  401. LPVOID lpobj
  402. ){
  403. LPOBJECT_MF lpobjMf;
  404. lpobjMf = (LPOBJECT_MF) lpobj;
  405. if (!--lpobjMf->nRecord) {
  406. lpobjMf->nRecord = RECORD_COUNT;
  407. if (!ContextCallBack ((lpobjMf->head.lpParent
  408. ? lpobjMf->head.lpParent
  409. : (LPOLEOBJECT) lpobjMf),
  410. OLE_QUERY_PAINT)) {
  411. lpobjMf->error = OLE_ERROR_ABORT;
  412. return FALSE;
  413. }
  414. }
  415. if (lpobjMf->fMetaDC) {
  416. #ifdef META_DEBUG
  417. PutMetaFuncName (lpMFR->rdFunction);
  418. #endif
  419. switch (lpMFR->rdFunction) {
  420. case META_SETWINDOWORG:
  421. SetPictOrg (lpobjMf, hdc, lpMFR->rdParm[1],
  422. lpMFR->rdParm[0], FALSE);
  423. return TRUE;
  424. case META_OFFSETWINDOWORG:
  425. SetPictOrg (lpobjMf, hdc, lpMFR->rdParm[1],
  426. lpMFR->rdParm[0], TRUE);
  427. return TRUE;
  428. case META_SETWINDOWEXT:
  429. SetPictExt (lpobjMf, hdc, lpMFR->rdParm[1], lpMFR->rdParm[0]);
  430. return TRUE;
  431. case META_SCALEWINDOWEXT:
  432. ScalePictExt (lpobjMf, hdc,
  433. lpMFR->rdParm[3], lpMFR->rdParm[2],
  434. lpMFR->rdParm[1], lpMFR->rdParm[0]);
  435. return TRUE;
  436. case META_SAVEDC:
  437. if (!PushDc (lpobjMf))
  438. return FALSE;
  439. break;
  440. case META_RESTOREDC:
  441. PopDc (lpobjMf);
  442. break;
  443. case META_SCALEVIEWPORTEXT:
  444. ScaleRectExt (lpobjMf, hdc,
  445. lpMFR->rdParm[3], lpMFR->rdParm[2],
  446. lpMFR->rdParm[1], lpMFR->rdParm[0]);
  447. return TRUE;
  448. case META_OFFSETVIEWPORTORG:
  449. #ifdef FIREWALLS
  450. ASSERT(0, "OffsetViewportOrg() in metafile");
  451. #endif
  452. return TRUE;
  453. case META_SETVIEWPORTORG:
  454. #ifdef FIREWALLS
  455. ASSERT(0, "SetViewportOrg() in metafile");
  456. #endif
  457. return TRUE;
  458. case META_SETVIEWPORTEXT:
  459. #ifdef FIREWALLS
  460. ASSERT(0, "SetViewportExt() in metafile");
  461. #endif
  462. return TRUE;
  463. case META_SETMAPMODE:
  464. #ifdef FIREWALLS
  465. ASSERT(lpMFR->rdParm[0] == MM_ANISOTROPIC,
  466. "SetmapMode() in metafile with invalid mapping mode");
  467. #endif
  468. return TRUE;
  469. default:
  470. break;
  471. }
  472. }
  473. else {
  474. switch (lpMFR->rdFunction) {
  475. int extX,extY;
  476. case META_SCALEWINDOWEXT:
  477. if (MGetWindowExt (hdc,&extX,&extY))
  478. {
  479. MSetWindowExt (
  480. hdc,
  481. MulDiv(extX, lpMFR->rdParm[3], lpMFR->rdParm[2]),
  482. MulDiv(extY, lpMFR->rdParm[1], lpMFR->rdParm[0])
  483. );
  484. return TRUE;
  485. }
  486. return FALSE;
  487. case META_SCALEVIEWPORTEXT:
  488. if (MGetViewportExt (hdc,&extX,&extY))
  489. {
  490. MSetViewportExt (
  491. hdc,
  492. MulDiv(extX, lpMFR->rdParm[3], lpMFR->rdParm[2]),
  493. MulDiv(extY, lpMFR->rdParm[1], lpMFR->rdParm[0])
  494. );
  495. return TRUE;
  496. }
  497. return FALSE;
  498. default:
  499. break;
  500. }
  501. }
  502. PlayMetaFileRecord (hdc, lpHTable, lpMFR, nObj);
  503. return TRUE;
  504. }
  505. void SetPictOrg (
  506. LPOBJECT_MF lpobj,
  507. HDC hdc,
  508. int xOrg,
  509. int yOrg,
  510. BOOL fOffset
  511. ){
  512. if (fOffset) {
  513. // it's OffsetWindowOrg() call
  514. lpobj->pCurMdc->xMwo += xOrg;
  515. lpobj->pCurMdc->yMwo += yOrg;
  516. }
  517. else {
  518. // it's SetWindowOrg()
  519. lpobj->pCurMdc->xMwo = xOrg;
  520. lpobj->pCurMdc->yMwo = yOrg;
  521. }
  522. if (lpobj->pCurMdc->xMwe && lpobj->pCurMdc->yMwe) {
  523. MSetWindowOrg (hdc,
  524. (lpobj->pCurMdc->xMwo - MulDiv (lpobj->pMetaInfo->xro,
  525. lpobj->pCurMdc->xMwe,
  526. lpobj->pCurMdc->xre)),
  527. (lpobj->pCurMdc->yMwo - MulDiv (lpobj->pMetaInfo->yro,
  528. lpobj->pCurMdc->yMwe,
  529. lpobj->pCurMdc->yre)));
  530. }
  531. }
  532. void SetPictExt (
  533. LPOBJECT_MF lpobj,
  534. HDC hdc,
  535. int xExt,
  536. int yExt
  537. ){
  538. lpobj->pCurMdc->xMwe = xExt;
  539. lpobj->pCurMdc->yMwe = yExt;
  540. MSetWindowExt (hdc,
  541. MulDiv (lpobj->pMetaInfo->xwe, xExt, lpobj->pCurMdc->xre),
  542. MulDiv (lpobj->pMetaInfo->ywe, yExt, lpobj->pCurMdc->yre));
  543. MSetWindowOrg (hdc,
  544. (lpobj->pCurMdc->xMwo
  545. - MulDiv (lpobj->pMetaInfo->xro, xExt, lpobj->pCurMdc->xre)),
  546. (lpobj->pCurMdc->yMwo
  547. - MulDiv (lpobj->pMetaInfo->yro, yExt, lpobj->pCurMdc->yre)));
  548. }
  549. void ScalePictExt (
  550. LPOBJECT_MF lpobj,
  551. HDC hdc,
  552. int xNum,
  553. int xDenom,
  554. int yNum,
  555. int yDenom
  556. ){
  557. SetPictExt (lpobj, hdc, MulDiv (lpobj->pCurMdc->xMwe, xNum, xDenom),
  558. MulDiv (lpobj->pCurMdc->yMwe, yNum, yDenom));
  559. }
  560. void ScaleRectExt (
  561. LPOBJECT_MF lpobj,
  562. HDC hdc,
  563. int xNum,
  564. int xDenom,
  565. int yNum,
  566. int yDenom
  567. ){
  568. lpobj->pCurMdc->xre = MulDiv (lpobj->pCurMdc->xre, xNum, xDenom);
  569. lpobj->pCurMdc->yre = MulDiv (lpobj->pCurMdc->yre, yNum, yDenom);
  570. SetPictExt (lpobj, hdc, lpobj->pCurMdc->xMwe, lpobj->pCurMdc->yMwe);
  571. }
  572. BOOL PushDc (LPOBJECT_MF lpobj)
  573. {
  574. HANDLE hNode = NULL;
  575. PMETADC pNode = NULL;
  576. if ((hNode = LocalAlloc (LMEM_MOVEABLE, sizeof (METADC)))
  577. && (pNode = (PMETADC) LocalLock (hNode))) {
  578. *pNode = *lpobj->pCurMdc;
  579. lpobj->pCurMdc->pNext = pNode;
  580. pNode->pNext = NULL;
  581. lpobj->pCurMdc = pNode;
  582. LocalUnlock (hNode);
  583. return TRUE;
  584. }
  585. if (pNode)
  586. LocalFree (hNode);
  587. lpobj->error = OLE_ERROR_MEMORY;
  588. return FALSE;
  589. }
  590. BOOL PopDc (LPOBJECT_MF lpobj)
  591. {
  592. PMETADC pPrev = (PMETADC) (lpobj->pMetaInfo);
  593. PMETADC pCur = ((PMETADC) (lpobj->pMetaInfo))->pNext;
  594. HANDLE hCur;
  595. if (!pCur)
  596. // more Pops than Pushes
  597. return FALSE;
  598. while (pCur->pNext) {
  599. pPrev = pCur;
  600. pCur = pCur->pNext;
  601. }
  602. if (hCur = LocalHandle ((MAPTYPE(WORD,LPSTR)) pCur))
  603. LocalFree (hCur);
  604. pPrev->pNext = NULL;
  605. lpobj->pCurMdc = pPrev;
  606. return TRUE;
  607. }
  608. void CleanStack(
  609. LPOBJECT_MF lpobj,
  610. HANDLE hMetaInfo
  611. ){
  612. PMETADC pCur = ((PMETADC) (lpobj->pMetaInfo))->pNext;
  613. HANDLE hCur;
  614. while (pCur) {
  615. hCur = LocalHandle ((MAPTYPE(WORD,LPSTR)) pCur);
  616. ((PMETADC) (lpobj->pMetaInfo))->pNext = pCur = pCur->pNext;
  617. if (hCur)
  618. LocalFree (hCur);
  619. }
  620. LocalFree (hMetaInfo);
  621. lpobj->fMetaDC = FALSE;
  622. lpobj->pCurMdc = NULL;
  623. lpobj->pMetaInfo = NULL;
  624. }
  625. #ifdef META_DEBUG
  626. void PutMetaFuncName (WORD value)
  627. {
  628. switch (value) {
  629. case META_SETBKCOLOR:
  630. OutputDebugString ("SetBkColor ");
  631. break;
  632. case META_SETBKMODE:
  633. OutputDebugString ("SetBkMode ");
  634. break;
  635. case META_SETMAPMODE:
  636. OutputDebugString ("SetMapMode ");
  637. break;
  638. case META_SETROP2:
  639. OutputDebugString ("SetRop2 ");
  640. break;
  641. case META_SETRELABS:
  642. OutputDebugString ("SetRelabs ");
  643. break;
  644. case META_SETPOLYFILLMODE:
  645. OutputDebugString ("SetPolyfillMode ");
  646. break;
  647. case META_SETSTRETCHBLTMODE:
  648. OutputDebugString ("SetStretchBltMode ");
  649. break;
  650. case META_SETTEXTCHAREXTRA:
  651. OutputDebugString ("SetTextCharExtra ");
  652. break;
  653. case META_SETTEXTCOLOR:
  654. OutputDebugString ("SetTextColor ");
  655. break;
  656. case META_SETTEXTJUSTIFICATION:
  657. OutputDebugString ("SetTextJustification ");
  658. break;
  659. case META_SETWINDOWORG:
  660. OutputDebugString ("SetWindowOrg ");
  661. break;
  662. case META_SETWINDOWEXT:
  663. OutputDebugString ("SetWindowExt ");
  664. break;
  665. case META_SETVIEWPORTORG:
  666. OutputDebugString ("SetViewportOrg ");
  667. break;
  668. case META_SETVIEWPORTEXT:
  669. OutputDebugString ("SetViewportExt ");
  670. break;
  671. case META_OFFSETWINDOWORG:
  672. OutputDebugString ("OffsetWindowOrg ");
  673. break;
  674. case META_SCALEWINDOWEXT:
  675. OutputDebugString ("ScaleWindowExt ");
  676. break;
  677. case META_OFFSETVIEWPORTORG:
  678. OutputDebugString ("OffsetViewportOrg ");
  679. break;
  680. case META_SCALEVIEWPORTEXT:
  681. OutputDebugString ("ScaleViewportExt ");
  682. break;
  683. case META_LINETO:
  684. OutputDebugString ("LineTo ");
  685. break;
  686. case META_MOVETO:
  687. OutputDebugString ("MoveTo ");
  688. break;
  689. case META_EXCLUDECLIPRECT:
  690. OutputDebugString ("ExcludeCliprect ");
  691. break;
  692. case META_INTERSECTCLIPRECT:
  693. OutputDebugString ("IntersectCliprect ");
  694. break;
  695. case META_ARC:
  696. OutputDebugString ("Arc ");
  697. break;
  698. case META_ELLIPSE:
  699. OutputDebugString ("Ellipse ");
  700. break;
  701. case META_FLOODFILL:
  702. OutputDebugString ("FloodFill ");
  703. break;
  704. case META_PIE:
  705. OutputDebugString ("Pie ");
  706. break;
  707. case META_RECTANGLE:
  708. OutputDebugString ("Rectangle ");
  709. break;
  710. case META_ROUNDRECT:
  711. OutputDebugString ("RoundRect ");
  712. break;
  713. case META_PATBLT:
  714. OutputDebugString ("PatBlt ");
  715. break;
  716. case META_SAVEDC:
  717. OutputDebugString ("SaveDC ");
  718. break;
  719. case META_SETPIXEL:
  720. OutputDebugString ("SetPixel ");
  721. break;
  722. case META_OFFSETCLIPRGN:
  723. OutputDebugString ("OffsetClipRegion ");
  724. break;
  725. case META_TEXTOUT:
  726. OutputDebugString ("TextOut ");
  727. break;
  728. case META_BITBLT:
  729. OutputDebugString ("BitBlt ");
  730. break;
  731. case META_STRETCHBLT:
  732. OutputDebugString ("StrechBlt ");
  733. break;
  734. case META_POLYGON:
  735. OutputDebugString ("Polygon ");
  736. break;
  737. case META_POLYLINE:
  738. OutputDebugString ("PolyLine ");
  739. break;
  740. case META_ESCAPE:
  741. OutputDebugString ("Escape ");
  742. break;
  743. case META_RESTOREDC:
  744. OutputDebugString ("RestoreDC ");
  745. break;
  746. case META_FILLREGION:
  747. OutputDebugString ("FillRegion ");
  748. break;
  749. case META_FRAMEREGION:
  750. OutputDebugString ("FrameRegion ");
  751. break;
  752. case META_INVERTREGION:
  753. OutputDebugString ("InvertRegion ");
  754. break;
  755. case META_PAINTREGION:
  756. OutputDebugString ("PaintRegion ");
  757. break;
  758. case META_SELECTCLIPREGION:
  759. OutputDebugString ("SelectClipRegion ");
  760. break;
  761. case META_SELECTOBJECT:
  762. OutputDebugString ("SelectObject ");
  763. break;
  764. case META_SETTEXTALIGN:
  765. OutputDebugString ("SetTextAlign ");
  766. break;
  767. case META_DRAWTEXT:
  768. OutputDebugString ("DrawText");
  769. break;
  770. case META_CHORD:
  771. OutputDebugString ("Chord ");
  772. break;
  773. case META_SETMAPPERFLAGS:
  774. OutputDebugString ("SetMapperFlags ");
  775. break;
  776. case META_EXTTEXTOUT:
  777. OutputDebugString ("ExtTextOut ");
  778. break;
  779. case META_SETDIBTODEV:
  780. OutputDebugString ("SetDIBitsToDevice ");
  781. break;
  782. case META_SELECTPALETTE:
  783. OutputDebugString ("SelectPalette ");
  784. break;
  785. case META_REALIZEPALETTE:
  786. OutputDebugString ("RealizePalette ");
  787. break;
  788. case META_ANIMATEPALETTE:
  789. OutputDebugString ("AnimatePalette ");
  790. break;
  791. case META_SETPALENTRIES:
  792. OutputDebugString ("SetPaletteEntries ");
  793. break;
  794. case META_POLYPOLYGON:
  795. OutputDebugString ("PolyPolygon ");
  796. break;
  797. case META_RESIZEPALETTE:
  798. OutputDebugString ("ResizePalette ");
  799. break;
  800. case META_DIBBITBLT:
  801. OutputDebugString ("DibBitBlt ");
  802. break;
  803. case META_DIBSTRETCHBLT:
  804. OutputDebugString ("DibStrechBlt ");
  805. break;
  806. case META_DIBCREATEPATTERNBRUSH:
  807. OutputDebugString ("DibCreatePatternBrush ");
  808. break;
  809. case META_STRETCHDIB:
  810. OutputDebugString ("StretchDIBits ");
  811. break;
  812. case META_DELETEOBJECT:
  813. OutputDebugString ("DeleteObject ");
  814. break;
  815. case META_CREATEPALETTE:
  816. OutputDebugString ("CreatePalette ");
  817. break;
  818. case META_CREATEBRUSH:
  819. OutputDebugString ("CreateBrush ");
  820. break;
  821. case META_CREATEPATTERNBRUSH:
  822. OutputDebugString ("CreatePatternBrush ");
  823. break;
  824. case META_CREATEPENINDIRECT:
  825. OutputDebugString ("CreatePenIndirect ");
  826. break;
  827. case META_CREATEFONTINDIRECT:
  828. OutputDebugString ("CreateFontIndirect ");
  829. break;
  830. case META_CREATEBRUSHINDIRECT:
  831. OutputDebugString ("CreateBrushIndirect ");
  832. break;
  833. case META_CREATEBITMAPINDIRECT:
  834. OutputDebugString ("CreateBitmapIndirect ");
  835. break;
  836. case META_CREATEBITMAP:
  837. OutputDebugString ("CreateBitmap ");
  838. break;
  839. case META_CREATEREGION:
  840. OutputDebugString ("CreateRegion ");
  841. break;
  842. default:
  843. OutputDebugString ("Invalid+Function+encountered ");
  844. break;
  845. }
  846. }
  847. #endif
  848. ////////////////////////////////////////////////////////////////////////////
  849. // ENHMETAFILE draw routines
  850. ////////////////////////////////////////////////////////////////////////////
  851. OLESTATUS FARINTERNAL EmfDraw (
  852. LPOLEOBJECT lpoleobj,
  853. HDC hdc,
  854. OLE_CONST RECT FAR* lprc,
  855. OLE_CONST RECT FAR* lpWrc,
  856. HDC hdcTarget
  857. ){
  858. LPOBJECT_EMF lpobj = (LPOBJECT_EMF) lpoleobj;
  859. UNREFERENCED_PARAMETER(hdcTarget);
  860. UNREFERENCED_PARAMETER(lpWrc);
  861. if (!lpobj->hemf)
  862. return OLE_ERROR_BLANK;
  863. lpobj->nRecord = RECORD_COUNT;
  864. lpobj->fMetaDC = OleIsDcMeta (hdc);
  865. if (!SaveDC(hdc))
  866. return OLE_ERROR_MEMORY;
  867. IntersectClipRect (hdc, lprc->left, lprc->top,
  868. lprc->right, lprc->bottom);
  869. lpobj->error = OLE_OK;
  870. EmfInterruptiblePaint(lpobj, hdc, (LPRECT)lprc);
  871. RestoreDC(hdc, -1);
  872. return lpobj->error;
  873. }
  874. void INTERNAL EmfInterruptiblePaint (
  875. LPOBJECT_EMF lpobj,
  876. HDC hdc ,
  877. LPRECT lprc
  878. ){
  879. EnumEnhMetaFile (hdc,(HENHMETAFILE)lpobj->hemf, (ENHMFENUMPROC)EmfCallbackFunc, (LPVOID)lpobj, lprc);
  880. }
  881. int FARINTERNAL EmfCallbackFunc (
  882. HDC hdc,
  883. LPHANDLETABLE lpHTable,
  884. LPENHMETARECORD lpEMFR,
  885. int nObj,
  886. LPVOID lpobj
  887. ){
  888. LPOBJECT_EMF lpobjEmf = (LPOBJECT_EMF) lpobj;
  889. if (!--lpobjEmf->nRecord) {
  890. lpobjEmf->nRecord = RECORD_COUNT;
  891. if (!ContextCallBack ((lpobjEmf->head.lpParent
  892. ? lpobjEmf->head.lpParent
  893. : (LPOLEOBJECT) lpobjEmf),
  894. OLE_QUERY_PAINT)) {
  895. lpobjEmf->error = OLE_ERROR_ABORT;
  896. return FALSE;
  897. }
  898. }
  899. PlayEnhMetaFileRecord (hdc, lpHTable, lpEMFR, nObj);
  900. return TRUE;
  901. }