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.

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