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.

1130 lines
30 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. return OLE_ERROR_DRAW;
  361. }
  362. if (!(hInfo = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
  363. sizeof(METAINFO))))
  364. return OLE_ERROR_MEMORY;
  365. if (!(lpobj->pMetaInfo = (PMETAINFO) LocalLock (hInfo))) {
  366. LocalFree (hInfo);
  367. return OLE_ERROR_MEMORY;
  368. }
  369. LocalUnlock (hInfo);
  370. lpobj->pCurMdc = (PMETADC) (lpobj->pMetaInfo);
  371. lpobj->pMetaInfo->xwo = lpWrc->left;
  372. lpobj->pMetaInfo->ywo = lpWrc->top;
  373. lpobj->pMetaInfo->xwe = lpWrc->right;
  374. lpobj->pMetaInfo->ywe = lpWrc->bottom;
  375. lpobj->pMetaInfo->xro = lpRrc->left - lpWrc->left;
  376. lpobj->pMetaInfo->yro = lpRrc->top - lpWrc->top;
  377. lpobj->pCurMdc->xre = lpRrc->right - lpRrc->left;
  378. lpobj->pCurMdc->yre = lpRrc->bottom - lpRrc->top;
  379. }
  380. lpobj->error = OLE_OK;
  381. MfInterruptiblePaint(lpobj, hdc);
  382. if (lpobj->fMetaDC)
  383. CleanStack (lpobj, hInfo);
  384. RestoreDC (hdc, iOldDc);
  385. return lpobj->error;
  386. }
  387. void INTERNAL MfInterruptiblePaint (
  388. LPOBJECT_MF lpobj,
  389. HDC hdc
  390. ){
  391. EnumMetaFile (hdc,lpobj->mfp.hMF, (MFENUMPROC)MfCallbackFunc, (LPARAM)lpobj);
  392. }
  393. BOOL APIENTRY MfCallbackFunc (
  394. HDC hdc,
  395. LPHANDLETABLE lpHTable,
  396. LPMETARECORD lpMFR,
  397. int nObj,
  398. LPVOID lpobj
  399. ){
  400. LPOBJECT_MF lpobjMf;
  401. lpobjMf = (LPOBJECT_MF) lpobj;
  402. if (!--lpobjMf->nRecord) {
  403. lpobjMf->nRecord = RECORD_COUNT;
  404. if (!ContextCallBack ((lpobjMf->head.lpParent
  405. ? lpobjMf->head.lpParent
  406. : (LPOLEOBJECT) lpobjMf),
  407. OLE_QUERY_PAINT)) {
  408. lpobjMf->error = OLE_ERROR_ABORT;
  409. return FALSE;
  410. }
  411. }
  412. if (lpobjMf->fMetaDC) {
  413. #ifdef META_DEBUG
  414. PutMetaFuncName (lpMFR->rdFunction);
  415. #endif
  416. switch (lpMFR->rdFunction) {
  417. case META_SETWINDOWORG:
  418. SetPictOrg (lpobjMf, hdc, lpMFR->rdParm[1],
  419. lpMFR->rdParm[0], FALSE);
  420. return TRUE;
  421. case META_OFFSETWINDOWORG:
  422. SetPictOrg (lpobjMf, hdc, lpMFR->rdParm[1],
  423. lpMFR->rdParm[0], TRUE);
  424. return TRUE;
  425. case META_SETWINDOWEXT:
  426. SetPictExt (lpobjMf, hdc, lpMFR->rdParm[1], lpMFR->rdParm[0]);
  427. return TRUE;
  428. case META_SCALEWINDOWEXT:
  429. ScalePictExt (lpobjMf, hdc,
  430. lpMFR->rdParm[3], lpMFR->rdParm[2],
  431. lpMFR->rdParm[1], lpMFR->rdParm[0]);
  432. return TRUE;
  433. case META_SAVEDC:
  434. if (!PushDc (lpobjMf))
  435. return FALSE;
  436. break;
  437. case META_RESTOREDC:
  438. PopDc (lpobjMf);
  439. break;
  440. case META_SCALEVIEWPORTEXT:
  441. ScaleRectExt (lpobjMf, hdc,
  442. lpMFR->rdParm[3], lpMFR->rdParm[2],
  443. lpMFR->rdParm[1], lpMFR->rdParm[0]);
  444. return TRUE;
  445. case META_OFFSETVIEWPORTORG:
  446. return TRUE;
  447. case META_SETVIEWPORTORG:
  448. return TRUE;
  449. case META_SETVIEWPORTEXT:
  450. return TRUE;
  451. case META_SETMAPMODE:
  452. return TRUE;
  453. default:
  454. break;
  455. }
  456. }
  457. else {
  458. switch (lpMFR->rdFunction) {
  459. int extX,extY;
  460. case META_SCALEWINDOWEXT:
  461. if (MGetWindowExt (hdc,&extX,&extY))
  462. {
  463. MSetWindowExt (
  464. hdc,
  465. MulDiv(extX, lpMFR->rdParm[3], lpMFR->rdParm[2]),
  466. MulDiv(extY, lpMFR->rdParm[1], lpMFR->rdParm[0])
  467. );
  468. return TRUE;
  469. }
  470. return FALSE;
  471. case META_SCALEVIEWPORTEXT:
  472. if (MGetViewportExt (hdc,&extX,&extY))
  473. {
  474. MSetViewportExt (
  475. hdc,
  476. MulDiv(extX, lpMFR->rdParm[3], lpMFR->rdParm[2]),
  477. MulDiv(extY, lpMFR->rdParm[1], lpMFR->rdParm[0])
  478. );
  479. return TRUE;
  480. }
  481. return FALSE;
  482. default:
  483. break;
  484. }
  485. }
  486. PlayMetaFileRecord (hdc, lpHTable, lpMFR, nObj);
  487. return TRUE;
  488. }
  489. void SetPictOrg (
  490. LPOBJECT_MF lpobj,
  491. HDC hdc,
  492. int xOrg,
  493. int yOrg,
  494. BOOL fOffset
  495. ){
  496. if (fOffset) {
  497. // it's OffsetWindowOrg() call
  498. lpobj->pCurMdc->xMwo += xOrg;
  499. lpobj->pCurMdc->yMwo += yOrg;
  500. }
  501. else {
  502. // it's SetWindowOrg()
  503. lpobj->pCurMdc->xMwo = xOrg;
  504. lpobj->pCurMdc->yMwo = yOrg;
  505. }
  506. if (lpobj->pCurMdc->xMwe && lpobj->pCurMdc->yMwe) {
  507. MSetWindowOrg (hdc,
  508. (lpobj->pCurMdc->xMwo - MulDiv (lpobj->pMetaInfo->xro,
  509. lpobj->pCurMdc->xMwe,
  510. lpobj->pCurMdc->xre)),
  511. (lpobj->pCurMdc->yMwo - MulDiv (lpobj->pMetaInfo->yro,
  512. lpobj->pCurMdc->yMwe,
  513. lpobj->pCurMdc->yre)));
  514. }
  515. }
  516. void SetPictExt (
  517. LPOBJECT_MF lpobj,
  518. HDC hdc,
  519. int xExt,
  520. int yExt
  521. ){
  522. lpobj->pCurMdc->xMwe = xExt;
  523. lpobj->pCurMdc->yMwe = yExt;
  524. MSetWindowExt (hdc,
  525. MulDiv (lpobj->pMetaInfo->xwe, xExt, lpobj->pCurMdc->xre),
  526. MulDiv (lpobj->pMetaInfo->ywe, yExt, lpobj->pCurMdc->yre));
  527. MSetWindowOrg (hdc,
  528. (lpobj->pCurMdc->xMwo
  529. - MulDiv (lpobj->pMetaInfo->xro, xExt, lpobj->pCurMdc->xre)),
  530. (lpobj->pCurMdc->yMwo
  531. - MulDiv (lpobj->pMetaInfo->yro, yExt, lpobj->pCurMdc->yre)));
  532. }
  533. void ScalePictExt (
  534. LPOBJECT_MF lpobj,
  535. HDC hdc,
  536. int xNum,
  537. int xDenom,
  538. int yNum,
  539. int yDenom
  540. ){
  541. SetPictExt (lpobj, hdc, MulDiv (lpobj->pCurMdc->xMwe, xNum, xDenom),
  542. MulDiv (lpobj->pCurMdc->yMwe, yNum, yDenom));
  543. }
  544. void ScaleRectExt (
  545. LPOBJECT_MF lpobj,
  546. HDC hdc,
  547. int xNum,
  548. int xDenom,
  549. int yNum,
  550. int yDenom
  551. ){
  552. lpobj->pCurMdc->xre = MulDiv (lpobj->pCurMdc->xre, xNum, xDenom);
  553. lpobj->pCurMdc->yre = MulDiv (lpobj->pCurMdc->yre, yNum, yDenom);
  554. SetPictExt (lpobj, hdc, lpobj->pCurMdc->xMwe, lpobj->pCurMdc->yMwe);
  555. }
  556. BOOL PushDc (LPOBJECT_MF lpobj)
  557. {
  558. HANDLE hNode = NULL;
  559. PMETADC pNode = NULL;
  560. if ((hNode = LocalAlloc (LMEM_MOVEABLE, sizeof (METADC)))
  561. && (pNode = (PMETADC) LocalLock (hNode))) {
  562. *pNode = *lpobj->pCurMdc;
  563. lpobj->pCurMdc->pNext = pNode;
  564. pNode->pNext = NULL;
  565. lpobj->pCurMdc = pNode;
  566. LocalUnlock (hNode);
  567. return TRUE;
  568. }
  569. if (pNode)
  570. LocalFree (hNode);
  571. lpobj->error = OLE_ERROR_MEMORY;
  572. return FALSE;
  573. }
  574. BOOL PopDc (LPOBJECT_MF lpobj)
  575. {
  576. PMETADC pPrev = (PMETADC) (lpobj->pMetaInfo);
  577. PMETADC pCur = ((PMETADC) (lpobj->pMetaInfo))->pNext;
  578. HANDLE hCur;
  579. if (!pCur)
  580. // more Pops than Pushes
  581. return FALSE;
  582. while (pCur->pNext) {
  583. pPrev = pCur;
  584. pCur = pCur->pNext;
  585. }
  586. if (hCur = LocalHandle ((MAPTYPE(WORD,LPSTR)) pCur))
  587. LocalFree (hCur);
  588. pPrev->pNext = NULL;
  589. lpobj->pCurMdc = pPrev;
  590. return TRUE;
  591. }
  592. void CleanStack(
  593. LPOBJECT_MF lpobj,
  594. HANDLE hMetaInfo
  595. ){
  596. PMETADC pCur = ((PMETADC) (lpobj->pMetaInfo))->pNext;
  597. HANDLE hCur;
  598. while (pCur) {
  599. hCur = LocalHandle ((MAPTYPE(WORD,LPSTR)) pCur);
  600. ((PMETADC) (lpobj->pMetaInfo))->pNext = pCur = pCur->pNext;
  601. if (hCur)
  602. LocalFree (hCur);
  603. }
  604. LocalFree (hMetaInfo);
  605. lpobj->fMetaDC = FALSE;
  606. lpobj->pCurMdc = NULL;
  607. lpobj->pMetaInfo = NULL;
  608. }
  609. #ifdef META_DEBUG
  610. void PutMetaFuncName (WORD value)
  611. {
  612. switch (value) {
  613. case META_SETBKCOLOR:
  614. OutputDebugString ("SetBkColor ");
  615. break;
  616. case META_SETBKMODE:
  617. OutputDebugString ("SetBkMode ");
  618. break;
  619. case META_SETMAPMODE:
  620. OutputDebugString ("SetMapMode ");
  621. break;
  622. case META_SETROP2:
  623. OutputDebugString ("SetRop2 ");
  624. break;
  625. case META_SETRELABS:
  626. OutputDebugString ("SetRelabs ");
  627. break;
  628. case META_SETPOLYFILLMODE:
  629. OutputDebugString ("SetPolyfillMode ");
  630. break;
  631. case META_SETSTRETCHBLTMODE:
  632. OutputDebugString ("SetStretchBltMode ");
  633. break;
  634. case META_SETTEXTCHAREXTRA:
  635. OutputDebugString ("SetTextCharExtra ");
  636. break;
  637. case META_SETTEXTCOLOR:
  638. OutputDebugString ("SetTextColor ");
  639. break;
  640. case META_SETTEXTJUSTIFICATION:
  641. OutputDebugString ("SetTextJustification ");
  642. break;
  643. case META_SETWINDOWORG:
  644. OutputDebugString ("SetWindowOrg ");
  645. break;
  646. case META_SETWINDOWEXT:
  647. OutputDebugString ("SetWindowExt ");
  648. break;
  649. case META_SETVIEWPORTORG:
  650. OutputDebugString ("SetViewportOrg ");
  651. break;
  652. case META_SETVIEWPORTEXT:
  653. OutputDebugString ("SetViewportExt ");
  654. break;
  655. case META_OFFSETWINDOWORG:
  656. OutputDebugString ("OffsetWindowOrg ");
  657. break;
  658. case META_SCALEWINDOWEXT:
  659. OutputDebugString ("ScaleWindowExt ");
  660. break;
  661. case META_OFFSETVIEWPORTORG:
  662. OutputDebugString ("OffsetViewportOrg ");
  663. break;
  664. case META_SCALEVIEWPORTEXT:
  665. OutputDebugString ("ScaleViewportExt ");
  666. break;
  667. case META_LINETO:
  668. OutputDebugString ("LineTo ");
  669. break;
  670. case META_MOVETO:
  671. OutputDebugString ("MoveTo ");
  672. break;
  673. case META_EXCLUDECLIPRECT:
  674. OutputDebugString ("ExcludeCliprect ");
  675. break;
  676. case META_INTERSECTCLIPRECT:
  677. OutputDebugString ("IntersectCliprect ");
  678. break;
  679. case META_ARC:
  680. OutputDebugString ("Arc ");
  681. break;
  682. case META_ELLIPSE:
  683. OutputDebugString ("Ellipse ");
  684. break;
  685. case META_FLOODFILL:
  686. OutputDebugString ("FloodFill ");
  687. break;
  688. case META_PIE:
  689. OutputDebugString ("Pie ");
  690. break;
  691. case META_RECTANGLE:
  692. OutputDebugString ("Rectangle ");
  693. break;
  694. case META_ROUNDRECT:
  695. OutputDebugString ("RoundRect ");
  696. break;
  697. case META_PATBLT:
  698. OutputDebugString ("PatBlt ");
  699. break;
  700. case META_SAVEDC:
  701. OutputDebugString ("SaveDC ");
  702. break;
  703. case META_SETPIXEL:
  704. OutputDebugString ("SetPixel ");
  705. break;
  706. case META_OFFSETCLIPRGN:
  707. OutputDebugString ("OffsetClipRegion ");
  708. break;
  709. case META_TEXTOUT:
  710. OutputDebugString ("TextOut ");
  711. break;
  712. case META_BITBLT:
  713. OutputDebugString ("BitBlt ");
  714. break;
  715. case META_STRETCHBLT:
  716. OutputDebugString ("StrechBlt ");
  717. break;
  718. case META_POLYGON:
  719. OutputDebugString ("Polygon ");
  720. break;
  721. case META_POLYLINE:
  722. OutputDebugString ("PolyLine ");
  723. break;
  724. case META_ESCAPE:
  725. OutputDebugString ("Escape ");
  726. break;
  727. case META_RESTOREDC:
  728. OutputDebugString ("RestoreDC ");
  729. break;
  730. case META_FILLREGION:
  731. OutputDebugString ("FillRegion ");
  732. break;
  733. case META_FRAMEREGION:
  734. OutputDebugString ("FrameRegion ");
  735. break;
  736. case META_INVERTREGION:
  737. OutputDebugString ("InvertRegion ");
  738. break;
  739. case META_PAINTREGION:
  740. OutputDebugString ("PaintRegion ");
  741. break;
  742. case META_SELECTCLIPREGION:
  743. OutputDebugString ("SelectClipRegion ");
  744. break;
  745. case META_SELECTOBJECT:
  746. OutputDebugString ("SelectObject ");
  747. break;
  748. case META_SETTEXTALIGN:
  749. OutputDebugString ("SetTextAlign ");
  750. break;
  751. case META_DRAWTEXT:
  752. OutputDebugString ("DrawText");
  753. break;
  754. case META_CHORD:
  755. OutputDebugString ("Chord ");
  756. break;
  757. case META_SETMAPPERFLAGS:
  758. OutputDebugString ("SetMapperFlags ");
  759. break;
  760. case META_EXTTEXTOUT:
  761. OutputDebugString ("ExtTextOut ");
  762. break;
  763. case META_SETDIBTODEV:
  764. OutputDebugString ("SetDIBitsToDevice ");
  765. break;
  766. case META_SELECTPALETTE:
  767. OutputDebugString ("SelectPalette ");
  768. break;
  769. case META_REALIZEPALETTE:
  770. OutputDebugString ("RealizePalette ");
  771. break;
  772. case META_ANIMATEPALETTE:
  773. OutputDebugString ("AnimatePalette ");
  774. break;
  775. case META_SETPALENTRIES:
  776. OutputDebugString ("SetPaletteEntries ");
  777. break;
  778. case META_POLYPOLYGON:
  779. OutputDebugString ("PolyPolygon ");
  780. break;
  781. case META_RESIZEPALETTE:
  782. OutputDebugString ("ResizePalette ");
  783. break;
  784. case META_DIBBITBLT:
  785. OutputDebugString ("DibBitBlt ");
  786. break;
  787. case META_DIBSTRETCHBLT:
  788. OutputDebugString ("DibStrechBlt ");
  789. break;
  790. case META_DIBCREATEPATTERNBRUSH:
  791. OutputDebugString ("DibCreatePatternBrush ");
  792. break;
  793. case META_STRETCHDIB:
  794. OutputDebugString ("StretchDIBits ");
  795. break;
  796. case META_DELETEOBJECT:
  797. OutputDebugString ("DeleteObject ");
  798. break;
  799. case META_CREATEPALETTE:
  800. OutputDebugString ("CreatePalette ");
  801. break;
  802. case META_CREATEBRUSH:
  803. OutputDebugString ("CreateBrush ");
  804. break;
  805. case META_CREATEPATTERNBRUSH:
  806. OutputDebugString ("CreatePatternBrush ");
  807. break;
  808. case META_CREATEPENINDIRECT:
  809. OutputDebugString ("CreatePenIndirect ");
  810. break;
  811. case META_CREATEFONTINDIRECT:
  812. OutputDebugString ("CreateFontIndirect ");
  813. break;
  814. case META_CREATEBRUSHINDIRECT:
  815. OutputDebugString ("CreateBrushIndirect ");
  816. break;
  817. case META_CREATEBITMAPINDIRECT:
  818. OutputDebugString ("CreateBitmapIndirect ");
  819. break;
  820. case META_CREATEBITMAP:
  821. OutputDebugString ("CreateBitmap ");
  822. break;
  823. case META_CREATEREGION:
  824. OutputDebugString ("CreateRegion ");
  825. break;
  826. default:
  827. OutputDebugString ("Invalid+Function+encountered ");
  828. break;
  829. }
  830. }
  831. #endif
  832. ////////////////////////////////////////////////////////////////////////////
  833. // ENHMETAFILE draw routines
  834. ////////////////////////////////////////////////////////////////////////////
  835. OLESTATUS FARINTERNAL EmfDraw (
  836. LPOLEOBJECT lpoleobj,
  837. HDC hdc,
  838. OLE_CONST RECT FAR* lprc,
  839. OLE_CONST RECT FAR* lpWrc,
  840. HDC hdcTarget
  841. ){
  842. LPOBJECT_EMF lpobj = (LPOBJECT_EMF) lpoleobj;
  843. UNREFERENCED_PARAMETER(hdcTarget);
  844. UNREFERENCED_PARAMETER(lpWrc);
  845. if (!lpobj->hemf)
  846. return OLE_ERROR_BLANK;
  847. lpobj->nRecord = RECORD_COUNT;
  848. lpobj->fMetaDC = OleIsDcMeta (hdc);
  849. if (!SaveDC(hdc))
  850. return OLE_ERROR_MEMORY;
  851. IntersectClipRect (hdc, lprc->left, lprc->top,
  852. lprc->right, lprc->bottom);
  853. lpobj->error = OLE_OK;
  854. EmfInterruptiblePaint(lpobj, hdc, (LPRECT)lprc);
  855. RestoreDC(hdc, -1);
  856. return lpobj->error;
  857. }
  858. void INTERNAL EmfInterruptiblePaint (
  859. LPOBJECT_EMF lpobj,
  860. HDC hdc ,
  861. LPRECT lprc
  862. ){
  863. EnumEnhMetaFile (hdc,(HENHMETAFILE)lpobj->hemf, (ENHMFENUMPROC)EmfCallbackFunc, (LPVOID)lpobj, lprc);
  864. }
  865. int FARINTERNAL EmfCallbackFunc (
  866. HDC hdc,
  867. LPHANDLETABLE lpHTable,
  868. LPENHMETARECORD lpEMFR,
  869. int nObj,
  870. LPVOID lpobj
  871. ){
  872. LPOBJECT_EMF lpobjEmf = (LPOBJECT_EMF) lpobj;
  873. if (!--lpobjEmf->nRecord) {
  874. lpobjEmf->nRecord = RECORD_COUNT;
  875. if (!ContextCallBack ((lpobjEmf->head.lpParent
  876. ? lpobjEmf->head.lpParent
  877. : (LPOLEOBJECT) lpobjEmf),
  878. OLE_QUERY_PAINT)) {
  879. lpobjEmf->error = OLE_ERROR_ABORT;
  880. return FALSE;
  881. }
  882. }
  883. PlayEnhMetaFileRecord (hdc, lpHTable, lpEMFR, nObj);
  884. return TRUE;
  885. }