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.

1835 lines
61 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: Meta.c
  3. *
  4. * This file contains the routines for playing the GDI metafile. Most of these
  5. * routines are adopted from windows gdi code. Most of the code is from
  6. * win3.0 except for the GetEvent code which is taken from win2.1
  7. *
  8. * Created: 11-Oct-1989
  9. *
  10. * Copyright (c) 1985, 1986, 1987, 1988, 1989 Microsoft Corporation
  11. *
  12. *
  13. * Public Functions:
  14. * PlayMetaFile
  15. * PlayMetaFileRecord
  16. * GetMetaFile
  17. * DeleteMetaFile
  18. * Private Functions:
  19. * GetEvent
  20. * IsDIBBlackAndWhite
  21. *
  22. * History:
  23. * 02-Jul-1991 -by- John Colleran [johnc]
  24. * Combined From Win 3.1 and WLO 1.0 sources
  25. \***************************************************************************/
  26. #include <windows.h>
  27. #include <string.h>
  28. #ifdef WIN32
  29. #include "firewall.h"
  30. #endif
  31. #include "gdi16.h"
  32. HDC hScreenDC = 0;
  33. METACACHE MetaCache = { 0, 0, 0, 0 };
  34. UINT INTERNAL GetFileNumber (LPMETAFILE lpMF);
  35. HANDLE INTERNAL CreateBitmapForDC (HDC hMemDC, LPBITMAPINFOHEADER lpDIBInfo);
  36. WORD INTERNAL GetSizeOfColorTable (LPBITMAPINFOHEADER lpDIBInfo);
  37. #define MAX_META_DISPATCH 0x48
  38. FARPROC alpfnMetaFunc[MAX_META_DISPATCH+1] =
  39. /* 00 */ {(FARPROC)ScaleWindowExt,
  40. /* 01 */ (FARPROC)SetBkColor,
  41. /* 02 */ (FARPROC)SetBkMode,
  42. /* 03 */ (FARPROC)SetMapMode,
  43. /* 04 */ (FARPROC)SetROP2,
  44. /* 05 */ DEFIFWIN16((FARPROC)SetRelAbs),
  45. /* 06 */ (FARPROC)SetPolyFillMode,
  46. /* 07 */ (FARPROC)SetStretchBltMode,
  47. /* 08 */ (FARPROC)SetTextCharacterExtra,
  48. /* 09 */ (FARPROC)SetTextColor,
  49. /* 0A */ (FARPROC)SetTextJustification,
  50. /* 0B */ (FARPROC)SetWindowOrg,
  51. /* 0C */ (FARPROC)SetWindowExt,
  52. /* 0D */ (FARPROC)SetViewportOrg,
  53. /* 0E */ (FARPROC)SetViewportExt,
  54. /* 0F */ (FARPROC)OffsetWindowOrg,
  55. /* 10 */ 0,
  56. /* 11 */ DEFIFWIN16((FARPROC)OffsetViewportOrg),
  57. /* 12 */ DEFIFWIN16((FARPROC)ScaleViewportExt),
  58. /* 13 */ (FARPROC)LineTo,
  59. /* 14 */ DEFIFWIN16((FARPROC)MoveTo),
  60. /* 15 */ (FARPROC)ExcludeClipRect,
  61. /* 16 */ (FARPROC)IntersectClipRect,
  62. /* 17 */ (FARPROC)Arc,
  63. /* 18 */ (FARPROC)Ellipse,
  64. /* 19 */ (FARPROC)FloodFill,
  65. /* 1A */ (FARPROC)Pie,
  66. /* 1B */ (FARPROC)Rectangle,
  67. /* 1C */ (FARPROC)RoundRect,
  68. /* 1D */ (FARPROC)PatBlt,
  69. /* 1E */ (FARPROC)SaveDC,
  70. /* 1F */ (FARPROC)SetPixel,
  71. /* 20 */ (FARPROC)OffsetClipRgn,
  72. /* 21 */ 0, // TextOut,
  73. /* 22 */ 0, // BitBlt,
  74. /* 23 */ 0, // StretchBlt.
  75. /* 24 */ 0, // Polygon,
  76. /* 25 */ 0, // Polyline,
  77. /* 26 */ 0, // Escape,
  78. /* 27 */ (FARPROC)RestoreDC,
  79. /* 28 */ 0, // FillRegion,
  80. /* 29 */ 0, // FrameRegion,
  81. /* 2A */ 0, // InvertRegion,
  82. /* 2B */ 0, // PaintRegion,
  83. /* 2C */ (FARPROC)SelectClipRgn,
  84. /* 2D */ 0, // SelectObject,
  85. /* 2E */ (FARPROC)SetTextAlign,
  86. /* 2F */ 0, // DrawText,
  87. /* 30 */ (FARPROC)Chord,
  88. /* 31 */ (FARPROC)SetMapperFlags,
  89. /* 32 */ 0, // ExtTextOut,
  90. /* 33 */ 0, // SetDibsToDevice,
  91. /* 34 */ 0, // SelectPalette,
  92. /* 35 */ 0, // RealizePalette,
  93. /* 36 */ 0, // AnimatePalette,
  94. /* 37 */ 0, // SetPaletteEntries,
  95. /* 38 */ 0, // PolyPolygon,
  96. /* 39 */ 0, // ResizePalette,
  97. /* 3A */ 0,
  98. /* 3B */ 0,
  99. /* 3C */ 0,
  100. /* 3D */ 0,
  101. /* 3E */ 0,
  102. /* 3F */ 0,
  103. /* 40 */ 0, // DIBBitblt,
  104. /* 41 */ 0, // DIBStretchBlt,
  105. /* 42 */ 0, // DIBCreatePatternBrush,
  106. /* 43 */ 0, // StretchDIB,
  107. /* 44 */ 0,
  108. /* 45 */ 0,
  109. /* 46 */ 0,
  110. /* 47 */ 0,
  111. /* 48 */ (FARPROC)ExtFloodFill };
  112. #if 0 // this is going to gdi.dll
  113. /***************************** Public Function ****************************\
  114. * BOOL APIENTRY PlayMetaFile(hdc, hmf)
  115. * HDC hDC;
  116. * HMETAFILE hMF;
  117. *
  118. * Play a windows metafile.
  119. *
  120. * History:
  121. * Tue 27-Mar-1990 11:11:45 -by- Paul Klingler [paulk]
  122. * Ported from Windows
  123. \***************************************************************************/
  124. BOOL GDIENTRY PlayMetaFile(HDC hdc, HMETAFILE hmf)
  125. {
  126. WORD i;
  127. WORD noObjs;
  128. BOOL bPrint=FALSE;
  129. LPMETAFILE lpmf;
  130. int oldMapMode = -1;
  131. LPMETARECORD lpmr = NULL;
  132. LPHANDLETABLE pht = NULL;
  133. HANDLE hht = NULL;
  134. #ifndef WIN32
  135. HFONT hLFont;
  136. HBRUSH hLBrush;
  137. HPALETTE hLPal;
  138. HPEN hLPen;
  139. HRGN hClipRgn;
  140. HRGN hRegion;
  141. DWORD oldWndExt;
  142. DWORD oldVprtExt;
  143. #endif //WIN32
  144. GdiLogFunc("PlayMetaFile");
  145. if(!IsValidMetaFile(hmf))
  146. goto exitPlayMetaFile;
  147. if(lpmf = (LPMETAFILE)GlobalLock(hmf))
  148. {
  149. if((noObjs = lpmf->MetaFileHeader.mtNoObjects) > 0)
  150. {
  151. if(!(hht = GlobalAlloc(GMEM_ZEROINIT|GMEM_MOVEABLE,
  152. (sizeof(HANDLE) * lpmf->MetaFileHeader.mtNoObjects) + sizeof(WORD ))))
  153. {
  154. goto exitPlayMetaFile10;
  155. }
  156. pht = (LPHANDLETABLE)GlobalLock(hht);
  157. }
  158. #ifdef CR1
  159. IMP: Optmizations playing into another metafile. Look at the win3.0
  160. IMP: code
  161. #endif
  162. // !!!!! what if this is a metafile DC
  163. #ifndef WIN32
  164. /* save the old objects so we can put them back */
  165. hLPen = GetCurrentObject( hdc, OBJ_PEN );
  166. hLBrush = GetCurrentObject( hdc, OBJ_BRUSH);
  167. hLFont = GetCurrentObject( hdc, OBJ_FONT);
  168. hClipRgn = GetCurrentObject( hdc, OBJ_RGN);
  169. hLPal = GetCurrentObject( hdc, OBJ_PALETTE);
  170. if(hRegion = GetCurrentObject( hdc, OBJ_RGN))
  171. {
  172. if(hClipRgn = CreateRectRgn(0,0,0,0))
  173. CombineRgn(hClipRgn,hRegion,hRegion,RGN_COPY);
  174. }
  175. #endif // WIN32
  176. // we should really remove this abort proc thing.
  177. while(lpmr = GetEvent(lpmf,lpmr,FALSE))
  178. {
  179. #if 0 //!!!!!
  180. if(GET_pAbortProc(pdc))
  181. #else
  182. if( 0 )
  183. #endif //!!!!!
  184. {
  185. //!!!!! if((bPrint = (*(pdc->pAbortProc))(hdc,0)) == FALSE)
  186. {
  187. GetEvent(lpmf,lpmr,TRUE);
  188. RestoreDC(hdc,0);
  189. goto exitPlayMetaFile20;
  190. }
  191. }
  192. PlayMetaFileRecord(hdc,pht,lpmr,noObjs);
  193. }
  194. bPrint = TRUE;
  195. exitPlayMetaFile20:
  196. /* if we fail restoring an object, we need to select some
  197. default object so that we can DeleteObject any Metafile-
  198. selected objects */
  199. #ifndef WIN32
  200. if(!SelectObject(hdc,hLPen))
  201. SelectObject(hdc,GetStockObject(BLACK_PEN));
  202. if(!SelectObject(hdc,hLBrush))
  203. SelectObject(hdc,GetStockObject(BLACK_BRUSH));
  204. if(!SelectPalette(hdc, GetCurrentObject( hdc, OBJ_PALETTE), FALSE))
  205. SelectPalette(hdc, GetStockObject(DEFAULT_PALETTE), FALSE);
  206. if(!SelectObject(hdc,hLFont))
  207. {
  208. /* if we cannot select the original font back in, we
  209. ** select the system font. this will allow us to delete
  210. ** the metafile font selected. to insure that the system
  211. ** font gets selected, we reset the DC's transform to
  212. ** default. after the selection, we restore this stuff
  213. */
  214. oldVprtExt = GetViewportExt(hdc);
  215. oldWndExt = GetWindowExt(hdc);
  216. oldMapMode = SetMapMode(hdc,MM_TEXT);
  217. SelectObject(hdc,GetStockObject(SYSTEM_FONT));
  218. SetMapMode(hdc,oldMapMode);
  219. SetWindowExt(hdc,LOWORD (oldWndExt),HIWORD (oldWndExt));
  220. SetViewportExt(hdc,LOWORD (oldVprtExt),HIWORD (oldVprtExt));
  221. }
  222. if(hClipRgn)
  223. {
  224. SelectObject(hdc,hClipRgn);
  225. DeleteObject(hClipRgn);
  226. }
  227. #endif // WIN32
  228. for(i = 0; i < lpmf->MetaFileHeader.mtNoObjects; ++i)
  229. {
  230. if(pht->objectHandle[i])
  231. DeleteObject(pht->objectHandle[i]);
  232. }
  233. #ifndef WIN32
  234. /* if we fiddled with the map mode because we could not
  235. ** restore the original font, then maybe we can restore the
  236. ** font now */
  237. if(oldMapMode > 0)
  238. SelectObject(hdc,hLFont);
  239. #endif // WIN32
  240. if(hht)
  241. {
  242. GlobalUnlock(hht);
  243. GlobalFree(hht);
  244. }
  245. exitPlayMetaFile10:
  246. GlobalUnlock(hmf);
  247. }
  248. exitPlayMetaFile:
  249. return(bPrint);
  250. }
  251. #endif // this is going to gdi.dll
  252. /***************************** Internal Function **************************\
  253. * BOOL NEAR PASCAL IsDIBBlackAndWhite
  254. *
  255. * Check to see if this DIB is a black and white DIB (and should be
  256. * converted into a mono bitmap as opposed to a color bitmap).
  257. *
  258. * Returns: TRUE it is a B&W bitmap
  259. * FALSE this is for color
  260. *
  261. * Effects: ?
  262. *
  263. * Warnings: ?
  264. *
  265. * History:
  266. \***************************************************************************/
  267. BOOL INTERNAL IsDIBBlackAndWhite(LPBITMAPINFOHEADER lpDIBInfo)
  268. {
  269. LPDWORD lpRGB;
  270. GdiLogFunc3( " IsDIBBlackAndWhite");
  271. /* pointer color table */
  272. lpRGB = (LPDWORD)((LPBITMAPINFO)lpDIBInfo)->bmiColors;
  273. if ((lpDIBInfo->biBitCount == 1 && lpDIBInfo->biPlanes == 1)
  274. && (lpRGB[0] == (DWORD)0)
  275. && (lpRGB[1] == (DWORD)0xFFFFFF))
  276. return(TRUE);
  277. else
  278. return(FALSE);
  279. }
  280. /***************************** Internal Function **************************\
  281. * BigRead
  282. *
  283. * allows reads of greater than 64K
  284. *
  285. * Returns: Number of bytes read
  286. *
  287. \***************************************************************************/
  288. DWORD INTERNAL BigRead(UINT fileNumber, LPSTR lpRecord, DWORD dwSizeRec)
  289. {
  290. DWORD dwRead = dwSizeRec;
  291. HPBYTE hpStuff;
  292. GdiLogFunc2( " BigRead");
  293. hpStuff = (HPBYTE)lpRecord;
  294. while (dwRead > MAXFILECHUNK)
  295. {
  296. if (_lread(fileNumber, (LPSTR)hpStuff, MAXFILECHUNK) != MAXFILECHUNK)
  297. return(0);
  298. dwRead -= MAXFILECHUNK;
  299. hpStuff += MAXFILECHUNK;
  300. }
  301. if (_lread(fileNumber, (LPSTR)hpStuff, (UINT)dwRead) != (UINT)dwRead)
  302. return(0);
  303. return(dwSizeRec);
  304. }
  305. /***************************** Internal Function **************************\
  306. * UseStretchDIBits
  307. *
  308. * set this directly to the device using StretchDIBits.
  309. * if DIB is black&white, don't do this.
  310. *
  311. * Returns:
  312. * TRUE --- operation successful
  313. * FALSE -- decided not to use StretchDIBits
  314. *
  315. * Effects: ?
  316. *
  317. * Warnings: ?
  318. *
  319. * History:
  320. \***************************************************************************/
  321. BOOL INTERNAL UseStretchDIB(HDC hDC, WORD magic, LPMETARECORD lpMR)
  322. {
  323. LPBITMAPINFOHEADER lpDIBInfo;
  324. int sExtX, sExtY;
  325. int sSrcX, sSrcY;
  326. int DstX, DstY, DstXE, DstYE;
  327. if (magic == META_DIBBITBLT)
  328. {
  329. lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[8];
  330. DstX = lpMR->rdParm[7];
  331. DstY = lpMR->rdParm[6];
  332. sSrcX = lpMR->rdParm[3];
  333. sSrcY = lpMR->rdParm[2];
  334. DstXE = sExtX = lpMR->rdParm[5];
  335. DstYE = sExtY = lpMR->rdParm[4];
  336. }
  337. else
  338. {
  339. lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[10];
  340. DstX = lpMR->rdParm[9];
  341. DstY = lpMR->rdParm[8];
  342. DstXE = lpMR->rdParm[7];
  343. DstYE = lpMR->rdParm[6];
  344. sSrcX = lpMR->rdParm[5];
  345. sSrcY = lpMR->rdParm[4];
  346. sExtX = lpMR->rdParm[3];
  347. sExtY = lpMR->rdParm[2];
  348. }
  349. /* if DIB is black&white, we don't really want to do this */
  350. if (IsDIBBlackAndWhite(lpDIBInfo))
  351. return(FALSE);
  352. StretchDIBits(hDC, DstX, DstY, DstXE, DstYE,
  353. sSrcX, sSrcY, sExtX, sExtY,
  354. (LPBYTE)((LPSTR)lpDIBInfo + lpDIBInfo->biSize
  355. + GetSizeOfColorTable(lpDIBInfo)),
  356. (LPBITMAPINFO)lpDIBInfo, DIB_RGB_COLORS,
  357. (MAKELONG(lpMR->rdParm[1], lpMR->rdParm[0])));
  358. return(TRUE);
  359. }
  360. /***************************** Internal Function **************************\
  361. * GetEvent
  362. *
  363. * This routine will now open a disk metafile in READ_ONLY mode. This will
  364. * allow us to play read-only metafiles or to share such file.
  365. *
  366. * [amitc: 06/19/91]
  367. \***************************************************************************/
  368. LPMETARECORD INTERNAL GetEvent(LPMETAFILE lpMF, HPMETARECORD lpMR, BOOL bFree)
  369. // BOOL bFree; /* non-zero ==> done with metafile */
  370. {
  371. int fileNumber = 0;
  372. WORD i;
  373. LPWORD lpCache = NULL;
  374. LPWORD lpMRbuf;
  375. HANDLE hMF;
  376. DWORD rdSize;
  377. GdiLogFunc2( " GetEvent");
  378. #ifdef WIN32
  379. hMF = GlobalHandle(lpMF);
  380. #else
  381. hMF = LOWORD(GlobalHandle(HIWORD((DWORD)(lpMF))));
  382. #endif
  383. ASSERTGDI( hMF != (HANDLE)NULL, "GetEvent: Global Handle failed");
  384. if (lpMF->MetaFileHeader.mtType == MEMORYMETAFILE)
  385. {
  386. /* Are we at the end of the metafile */
  387. if(lpMR && lpMR->rdFunction == 0)
  388. return((LPMETARECORD)0);
  389. /* done with metafile, so free up the temp selector */
  390. else if (bFree)
  391. {
  392. if (lpMR)
  393. #ifndef WIN32
  394. FreeSelector(HIWORD(lpMR));
  395. #endif
  396. return((LPMETARECORD)0);
  397. }
  398. else
  399. {
  400. /* if we don't already have a selector, get one */
  401. if (lpMR == NULL)
  402. {
  403. #ifdef WIN32
  404. lpMR = (HPMETARECORD)((LPMETADATA)lpMF)->metaDataStuff;
  405. // lpMR = (LPMETARECORD)GlobalLock(lpMF->hMetaData);
  406. #else
  407. lpMR = (LPMETARECORD)MAKELP(AllocSelector(HIWORD((DWORD)&lpMF->MetaFileNumber)),LOWORD((DWORD)&lpMF->MetaFileNumber));
  408. #endif
  409. }
  410. else
  411. lpMR = (LPMETARECORD) (((HPWORD)lpMR)+lpMR->rdSize);
  412. /* end of the metafile. free up the selector we were using */
  413. if (lpMR->rdFunction == 0)
  414. {
  415. #ifndef WIN32
  416. FreeSelector(HIWORD(lpMR));
  417. #endif
  418. return((LPMETARECORD)0);
  419. }
  420. }
  421. return(lpMR);
  422. }
  423. else if (lpMF->MetaFileHeader.mtType == DISKMETAFILE)
  424. {
  425. if (bFree)
  426. goto errGetEvent; /* never TRUE on the first call to GetEvent */
  427. if (lpMR == NULL)
  428. {
  429. if ((fileNumber = OpenFile((LPSTR)lpMF->MetaFileBuffer.szPathName, (LPOFSTRUCT)&(lpMF->MetaFileBuffer), (WORD)OF_PROMPT|OF_REOPEN|OF_READ)) != -1)
  430. {
  431. if (lpMF->MetaFileRecordHandle = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE,(DWORD)(lpMF->MetaFileHeader.mtMaxRecord * sizeof(WORD))))
  432. {
  433. lpMR = (LPMETARECORD)GlobalLock(lpMF->MetaFileRecordHandle);
  434. lpMF->MetaFilePosition = _lread(lpMF->MetaFileNumber = fileNumber, (LPSTR)&lpMF->MetaFileHeader, sizeof(METAHEADER));
  435. // Check for an Aldus header
  436. if (*((LPDWORD)&(lpMF->MetaFileHeader)) == 0x9AC6CDD7)
  437. {
  438. _llseek( fileNumber, 22, 0);
  439. lpMF->MetaFilePosition = 22 + _lread(fileNumber,(LPSTR)(&(lpMF->MetaFileHeader)),sizeof(METAHEADER));
  440. }
  441. lpMF->MetaFileHeader.mtType = DISKMETAFILE;
  442. if (!MetaCache.hCache)
  443. {
  444. MetaCache.hCache = AllocBuffer(&MetaCache.wCacheSize);
  445. MetaCache.wCacheSize >>= 1;
  446. MetaCache.hMF = hMF;
  447. /* force cache fill on first access */
  448. MetaCache.wCachePos = MetaCache.wCacheSize;
  449. }
  450. if (!(lpMF->MetaFileBuffer.fFixedDisk))
  451. {
  452. _lclose(fileNumber);
  453. /* need to update the following for floppy files -- amitc */
  454. fileNumber = 0 ;
  455. lpMF->MetaFileNumber = 0 ;
  456. }
  457. }
  458. }
  459. else
  460. return((LPMETARECORD)0);
  461. }
  462. /* update fileNumber, this is so that floopy based files can be closed
  463. and not left open -- amitc */
  464. fileNumber = lpMF->MetaFileNumber ;
  465. if (lpMR)
  466. {
  467. if (MetaCache.hMF == hMF)
  468. {
  469. lpCache = (LPWORD) GlobalLock(MetaCache.hCache);
  470. lpMRbuf = (LPWORD) lpMR;
  471. // Make sure we can read the size and function fields
  472. if (MetaCache.wCachePos >= (WORD)(MetaCache.wCacheSize - 2))
  473. {
  474. WORD cwCopy;
  475. if (!fileNumber)
  476. if ((fileNumber = GetFileNumber(lpMF)) == -1)
  477. goto errGetEvent;
  478. // We need to fill up the cache but save any data already
  479. // in the cache
  480. cwCopy = MetaCache.wCacheSize - MetaCache.wCachePos;
  481. for (i = 0; i < cwCopy; i++)
  482. {
  483. lpCache[i] = lpCache[MetaCache.wCacheSize-(cwCopy-i)];
  484. }
  485. lpMF->MetaFilePosition += _lread(fileNumber,
  486. (LPSTR) (lpCache + cwCopy),
  487. (MetaCache.wCacheSize-cwCopy) << 1);
  488. MetaCache.wCachePos = 0;
  489. }
  490. lpCache += MetaCache.wCachePos;
  491. rdSize = ((LPMETARECORD)lpCache)->rdSize;
  492. /* Check for end */
  493. if (!((LPMETARECORD)lpCache)->rdFunction)
  494. goto errGetEvent;
  495. // Make sure we can read the rest of the metafile record
  496. if (rdSize + MetaCache.wCachePos > MetaCache.wCacheSize)
  497. {
  498. if (!fileNumber)
  499. if ((fileNumber = GetFileNumber(lpMF))
  500. == -1)
  501. goto errGetEvent;
  502. for (i=MetaCache.wCachePos; i < MetaCache.wCacheSize; ++i)
  503. *lpMRbuf++ = *lpCache++;
  504. lpMF->MetaFilePosition +=
  505. BigRead(fileNumber, (LPSTR) lpMRbuf,
  506. (DWORD)(rdSize
  507. + (DWORD)MetaCache.wCachePos
  508. - (DWORD)MetaCache.wCacheSize) << 1);
  509. // Mark the cache as depleted because we just read
  510. // directly into the metafile record rather than the cache
  511. MetaCache.wCachePos = MetaCache.wCacheSize;
  512. }
  513. else
  514. {
  515. ASSERTGDI( HIWORD(rdSize) == 0, "Huge rdsize");
  516. for (i = 0; i < LOWORD(rdSize); ++i)
  517. *lpMRbuf++ = *lpCache++;
  518. MetaCache.wCachePos += LOWORD(rdSize);
  519. }
  520. GlobalUnlock(MetaCache.hCache);
  521. return lpMR;
  522. }
  523. if ((fileNumber = GetFileNumber(lpMF)) == -1)
  524. goto errGetEvent;
  525. lpMF->MetaFilePosition += _lread(fileNumber, (LPSTR)&lpMR->rdSize, sizeof(DWORD));
  526. lpMF->MetaFilePosition += BigRead(fileNumber, (LPSTR)&lpMR->rdFunction, (DWORD)(lpMR->rdSize * sizeof(WORD)) - sizeof(DWORD));
  527. if (!(lpMF->MetaFileBuffer.fFixedDisk))
  528. {
  529. _lclose(fileNumber);
  530. lpMF->MetaFileNumber = 0 ;
  531. fileNumber = 0 ;
  532. }
  533. if (lpMR->rdFunction == 0)
  534. {
  535. errGetEvent:;
  536. if (lpMF->MetaFileBuffer.fFixedDisk || fileNumber)
  537. _lclose(lpMF->MetaFileNumber);
  538. GlobalUnlock(lpMF->MetaFileRecordHandle);
  539. GlobalFree(lpMF->MetaFileRecordHandle);
  540. lpMF->MetaFileNumber = 0;
  541. if (MetaCache.hMF == hMF)
  542. {
  543. if (lpCache)
  544. GlobalUnlock(MetaCache.hCache);
  545. GlobalFree(MetaCache.hCache);
  546. MetaCache.hCache = MetaCache.hMF = 0;
  547. }
  548. return((LPMETARECORD)0);
  549. }
  550. }
  551. return(lpMR);
  552. }
  553. return((LPMETARECORD)0);
  554. }
  555. /***************************** Internal Function **************************\
  556. * void GDIENTRY PlayMetaFileRecord
  557. *
  558. * Plays a metafile record by executing the GDI function call contained
  559. * withing the metafile record
  560. *
  561. * Effects:
  562. *
  563. \***************************************************************************/
  564. #if 0 // this is going to gdi.dll
  565. void
  566. GDIENTRY PlayMetaFileRecord(
  567. HDC hdc,
  568. LPHANDLETABLE lpHandleTable,
  569. LPMETARECORD lpMR,
  570. WORD noObjs
  571. )
  572. {
  573. WORD magic;
  574. HANDLE hObject;
  575. HANDLE hOldObject;
  576. HBRUSH hBrush;
  577. HRGN hRgn;
  578. HANDLE hPal;
  579. BOOL bExtraSel = FALSE;
  580. dprintf( 3," PlayMetaFileRecord 0x%lX", lpMR);
  581. if (!ISDCVALID(hdc))
  582. return;
  583. magic = lpMR->rdFunction;
  584. /* being safe, make sure that the lp will give us full access to
  585. ** the record header without overstepping a segment boundary.
  586. */
  587. #ifndef WIN32
  588. if ((unsigned)(LOWORD((DWORD)lpMR)) > 0x7000)
  589. {
  590. lpMR = (LPMETARECORD)MAKELP(AllocSelector(HIWORD((DWORD)lpMR)),LOWORD((DWORD)lpMR));
  591. bExtraSel = TRUE;
  592. }
  593. #endif // WIN32
  594. switch (magic & 255)
  595. {
  596. case (META_BITBLT & 255):
  597. case (META_STRETCHBLT & 255):
  598. {
  599. HDC hSDC;
  600. HANDLE hBitmap;
  601. LPBITMAP lpBitmap;
  602. int delta = 0;
  603. /* if playing into another Metafile, do direct copy */
  604. if (PlayIntoAMetafile(lpMR, hdc))
  605. goto errPlayMetaFileRecord20;
  606. if ((lpMR->rdSize - 3) == (magic >> 8))
  607. {
  608. hSDC = hdc;
  609. delta = 1;
  610. }
  611. else
  612. {
  613. if (hSDC = CreateCompatibleDC(hdc))
  614. {
  615. if (magic == META_BITBLT)
  616. lpBitmap = (LPBITMAP)&lpMR->rdParm[8];
  617. else
  618. lpBitmap = (LPBITMAP)&lpMR->rdParm[10];
  619. //!!!!! ALERT DWORD align on NT
  620. if (hBitmap = CreateBitmap(lpBitmap->bmWidth,
  621. lpBitmap->bmHeight,
  622. lpBitmap->bmPlanes,
  623. lpBitmap->bmBitsPixel,
  624. (LPBYTE)&lpBitmap->bmBits))
  625. hOldObject = SelectObject(hSDC, hBitmap);
  626. else
  627. goto errPlayMetaFileRecord10;
  628. }
  629. else
  630. goto errPlayMetaFileRecord20;
  631. }
  632. if (hSDC)
  633. {
  634. if (magic == META_BITBLT)
  635. BitBlt(hdc, lpMR->rdParm[7 + delta],
  636. lpMR->rdParm[6 + delta],
  637. lpMR->rdParm[5 + delta],
  638. lpMR->rdParm[4 + delta],
  639. hSDC,
  640. lpMR->rdParm[3],
  641. lpMR->rdParm[2],
  642. MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1]));
  643. else
  644. StretchBlt(hdc, lpMR->rdParm[9 + delta],
  645. lpMR->rdParm[8 + delta],
  646. lpMR->rdParm[7 + delta],
  647. lpMR->rdParm[6 + delta],
  648. hSDC,
  649. lpMR->rdParm[5],
  650. lpMR->rdParm[4],
  651. lpMR->rdParm[3],
  652. lpMR->rdParm[2],
  653. MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1]));
  654. }
  655. if (hSDC != hdc)
  656. {
  657. if (SelectObject(hSDC, hOldObject))
  658. DeleteObject(hBitmap);
  659. errPlayMetaFileRecord10:;
  660. DeleteDC(hSDC);
  661. errPlayMetaFileRecord20:;
  662. }
  663. }
  664. break;
  665. case (META_DIBBITBLT & 255):
  666. case (META_DIBSTRETCHBLT & 255):
  667. {
  668. HDC hSDC;
  669. HANDLE hBitmap;
  670. LPBITMAPINFOHEADER lpDIBInfo ;
  671. int delta = 0;
  672. HANDLE hOldPal;
  673. /* if playing into another metafile, do direct copy */
  674. if (PlayIntoAMetafile(lpMR, hdc))
  675. goto errPlayMetaFileRecord40;
  676. if ((lpMR->rdSize - 3) == (magic >> 8))
  677. {
  678. hSDC = hdc;
  679. delta = 1;
  680. }
  681. else
  682. {
  683. if( (magic & 255) == (META_DIBSTRETCHBLT & 255) )
  684. if (UseStretchDIB(hdc, magic, lpMR))
  685. goto errPlayMetaFileRecord40;
  686. if (hSDC = CreateCompatibleDC(hdc))
  687. {
  688. /* set up the memDC to have the same palette */
  689. hOldPal = SelectPalette(hSDC, GetCurrentObject(hdc,OBJ_PALETTE), TRUE);
  690. if (magic == META_DIBBITBLT)
  691. lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[8];
  692. else
  693. lpDIBInfo = (LPBITMAPINFOHEADER)&lpMR->rdParm[10];
  694. /* now create the bitmap for the MemDC and fill in the bits */
  695. /* the processing for old and new format of metafiles is
  696. different here (till hBitmap is obtained) */
  697. /* new metafile version */
  698. hBitmap = CreateBitmapForDC (hdc,lpDIBInfo);
  699. if (hBitmap)
  700. hOldObject = SelectObject (hSDC, hBitmap) ;
  701. else
  702. goto errPlayMetaFileRecord30 ;
  703. }
  704. else
  705. goto errPlayMetaFileRecord40;
  706. }
  707. if (hSDC)
  708. {
  709. if (magic == META_DIBBITBLT)
  710. BitBlt(hdc, lpMR->rdParm[7 + delta],
  711. lpMR->rdParm[6 + delta],
  712. lpMR->rdParm[5 + delta],
  713. lpMR->rdParm[4 + delta],
  714. hSDC,
  715. lpMR->rdParm[3],
  716. lpMR->rdParm[2],
  717. MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1]));
  718. else
  719. StretchBlt(hdc, lpMR->rdParm[9 + delta],
  720. lpMR->rdParm[8 + delta],
  721. lpMR->rdParm[7 + delta],
  722. lpMR->rdParm[6 + delta],
  723. hSDC,
  724. lpMR->rdParm[5],
  725. lpMR->rdParm[4],
  726. lpMR->rdParm[3],
  727. lpMR->rdParm[2],
  728. MAKELONG(lpMR->rdParm[0], lpMR->rdParm[1]));
  729. }
  730. if (hSDC != hdc)
  731. {
  732. /* Deselect hDC's palette from memDC */
  733. SelectPalette(hSDC, hOldPal, TRUE);
  734. if (SelectObject(hSDC, hOldObject))
  735. DeleteObject(hBitmap);
  736. errPlayMetaFileRecord30:;
  737. DeleteDC(hSDC);
  738. errPlayMetaFileRecord40:;
  739. }
  740. }
  741. break;
  742. case (META_SELECTOBJECT & 255):
  743. {
  744. HANDLE hObject;
  745. if (hObject = lpHandleTable->objectHandle[lpMR->rdParm[0]])
  746. SelectObject(hdc, hObject);
  747. }
  748. break;
  749. case (META_CREATEPENINDIRECT & 255):
  750. {
  751. #ifdef WIN32
  752. LOGPEN lp;
  753. lp.lopnStyle = lpMR->rdParm[0];
  754. lp.lopnWidth.x = lpMR->rdParm[1];
  755. lp.lopnColor = *((COLORREF *)&lpMR->rdParm[3]);
  756. if (hObject = CreatePenIndirect(&lp))
  757. #else
  758. if (hObject = CreatePenIndirect((LPLOGPEN)&lpMR->rdParm[0]))
  759. #endif
  760. AddToHandleTable(lpHandleTable, hObject, noObjs);
  761. break;
  762. }
  763. case (META_CREATEFONTINDIRECT & 255):
  764. {
  765. LOGFONT lf;
  766. LPLOGFONT lplf = &lf;
  767. LOGFONT32FROM16( lplf, ((LPLOGFONT)&lpMR->rdParm[0]));
  768. if (hObject = CreateFontIndirect(lplf))
  769. AddToHandleTable(lpHandleTable, hObject, noObjs);
  770. }
  771. break;
  772. case (META_CREATEPATTERNBRUSH & 255):
  773. {
  774. HANDLE hBitmap;
  775. LPBITMAP lpBitmap;
  776. lpBitmap = (LPBITMAP)lpMR->rdParm;
  777. //!!!!! ALERT DWORD align on NT
  778. if (hBitmap = CreateBitmapIndirect(lpBitmap))
  779. {
  780. LPBITMAPINFO lpbmInfo;
  781. HANDLE hmemInfo;
  782. hmemInfo = GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE,
  783. sizeof(BITMAPINFO) + 2<<(lpBitmap->bmPlanes*lpBitmap->bmBitsPixel));
  784. lpbmInfo = (LPBITMAPINFO)GlobalLock( hmemInfo);
  785. lpbmInfo->bmiHeader.biPlanes = lpBitmap->bmPlanes;
  786. lpbmInfo->bmiHeader.biBitCount = lpBitmap->bmBitsPixel;
  787. SetDIBits( (HDC)NULL, hBitmap, 0, lpBitmap->bmHeight,
  788. (LPBYTE)&lpMR->rdParm[8], lpbmInfo, DIB_RGB_COLORS );
  789. if (hObject = CreatePatternBrush(hBitmap))
  790. AddToHandleTable(lpHandleTable, hObject, noObjs);
  791. GlobalUnlock(hmemInfo);
  792. GlobalFree(hmemInfo);
  793. DeleteObject(hBitmap);
  794. }
  795. }
  796. break;
  797. case (META_DIBCREATEPATTERNBRUSH & 255):
  798. {
  799. HDC hMemDC ;
  800. HANDLE hBitmap;
  801. LPBITMAPINFOHEADER lpDIBInfo ;
  802. WORD nDIBSize; /* number of WORDs in packed DIB */
  803. HANDLE hDIB;
  804. LPWORD lpDIB;
  805. LPWORD lpSourceDIB;
  806. WORD i;
  807. if (lpMR->rdParm[0] == BS_PATTERN)
  808. {
  809. /* the address of the second paramter is the address of the DIB
  810. header, extract it */
  811. lpDIBInfo = (BITMAPINFOHEADER FAR *) &lpMR->rdParm[2];
  812. /* now create a device dependend bitmap compatible to the default
  813. screen DC - hScreenDC and extract the bits from the DIB into it.
  814. The following function does all these, and returns a HANDLE
  815. to the device dependent BItmap. */
  816. /* we will use a dummy memory DC compatible to the screen DC */
  817. hMemDC = CreateCompatibleDC (hScreenDC) ;
  818. hBitmap = CreateBitmapForDC (hScreenDC,lpDIBInfo) ;
  819. if (hBitmap)
  820. {
  821. if (hObject = CreatePatternBrush(hBitmap))
  822. AddToHandleTable(lpHandleTable, hObject, noObjs);
  823. DeleteObject(hBitmap);
  824. }
  825. /* delete the dummy memory DC for new version Metafiles*/
  826. DeleteDC (hMemDC) ;
  827. }
  828. /* this is a DIBPattern brush */
  829. else
  830. {
  831. /* get size of just the packed DIB */
  832. nDIBSize = (WORD) (lpMR->rdSize - 4);
  833. if ((hDIB = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE,(LONG)(nDIBSize << 1))))
  834. {
  835. lpDIB = (WORD FAR *) GlobalLock (hDIB);
  836. lpSourceDIB = (WORD FAR *)&lpMR->rdParm[2];
  837. /* copy the DIB into our new memory block */
  838. for (i = 0; i < nDIBSize; i++)
  839. *lpDIB++ = *lpSourceDIB++;
  840. GlobalUnlock (hDIB);
  841. if (hObject = CreateDIBPatternBrush(hDIB, lpMR->rdParm[1]))
  842. AddToHandleTable(lpHandleTable, hObject, noObjs);
  843. GlobalFree(hDIB);
  844. }
  845. }
  846. }
  847. break;
  848. case (META_CREATEBRUSHINDIRECT & 255):
  849. {
  850. #ifdef WIN32
  851. LOGBRUSH lb;
  852. lb.lbStyle = lpMR->rdParm[0];
  853. lb.lbColor = *((COLORREF *)&lpMR->rdParm[1]);
  854. lb.lbHatch = lpMR->rdParm[3];
  855. if (hObject = CreateBrushIndirect(&lb))
  856. #else
  857. if (hObject = CreateBrushIndirect((LPLOGBRUSH)&lpMR->rdParm[0]))
  858. #endif
  859. AddToHandleTable(lpHandleTable, hObject, noObjs);
  860. break;
  861. }
  862. case (META_POLYLINE & 255):
  863. {
  864. LPPOINT lppt;
  865. Polyline(hdc, (lppt=CONVERTPTS(&lpMR->rdParm[1],lpMR->rdParm[0])), lpMR->rdParm[0]);
  866. FREECONVERT(lppt);
  867. break;
  868. }
  869. case (META_POLYGON & 255):
  870. {
  871. LPPOINT lppt;
  872. Polygon(hdc, (lppt=CONVERTPTS(&lpMR->rdParm[1],lpMR->rdParm[0])), lpMR->rdParm[0]);
  873. FREECONVERT(lppt);
  874. break;
  875. }
  876. case (META_POLYPOLYGON & 255):
  877. {
  878. LPPOINT lppt;
  879. #ifdef WIN32
  880. WORD cPts=0;
  881. WORD ii;
  882. for(ii=0; ii<lpMR->rdParm[0]; ii++)
  883. cPts += ((LPWORD)&lpMR->rdParm[1])[ii];
  884. #endif // WIN32
  885. PolyPolygon(hdc,
  886. (lppt=CONVERTPTS(&lpMR->rdParm[1] + lpMR->rdParm[0], cPts)),
  887. (LPINT)&lpMR->rdParm[1],
  888. lpMR->rdParm[0]);
  889. FREECONVERT(lppt);
  890. }
  891. break;
  892. case (META_EXTTEXTOUT & 255):
  893. {
  894. LPWORD lpdx;
  895. LPSTR lpch;
  896. LPRECT lprt;
  897. lprt = (lpMR->rdParm[3] & (ETO_OPAQUE|ETO_CLIPPED)) ? (LPRECT)&lpMR->rdParm[4] : 0;
  898. lpch = (LPSTR)&lpMR->rdParm[4] + ((lprt) ? sizeof(RECT) : 0);
  899. /* dx array starts at next word boundary after char string */
  900. lpdx = (LPWORD)(lpch + ((lpMR->rdParm[2] + 1) & 0xFFFE));
  901. /* check to see if there is a Dx array by seeing if
  902. structure ends after the string itself
  903. */
  904. if ( ((DWORD)((LPWORD)lpdx - (LPWORD)(lpMR))) >= lpMR->rdSize)
  905. lpdx = NULL;
  906. else
  907. lpdx = (LPWORD)CONVERTINTS((signed short FAR *)lpdx, lpMR->rdParm[2]);
  908. ExtTextOut(hdc, lpMR->rdParm[1], lpMR->rdParm[0], lpMR->rdParm[3],
  909. lprt, (LPSTR)lpch, lpMR->rdParm[2], (LPINT)lpdx);
  910. if (lpdx != (LPWORD)NULL)
  911. FREECONVERT(lpdx);
  912. break;
  913. }
  914. case (META_TEXTOUT & 255):
  915. TextOut(hdc, lpMR->rdParm[lpMR->rdSize-4], lpMR->rdParm[lpMR->rdSize-5], (LPSTR)&lpMR->rdParm[1], lpMR->rdParm[0]);
  916. break;
  917. case (META_ESCAPE & 255):
  918. {
  919. LPSTR lpStuff;
  920. if (lpMR->rdParm[0] != MFCOMMENT)
  921. {
  922. lpStuff = (LPSTR)&lpMR->rdParm[2];
  923. #ifdef OLDEXTTEXTOUT
  924. if (lpMR->rdParm[0] == EXTTEXTOUT)
  925. {
  926. EXTTEXTDATA ExtData;
  927. ExtData.xPos = lpMR->rdParm[2];
  928. ExtData.yPos = lpMR->rdParm[3];
  929. ExtData.cch = lpMR->rdParm[4];
  930. ExtData.rcClip = *((LPRECT)&lpMR->rdParm[5]);
  931. ExtData.lpString = (LPSTR)&lpMR->rdParm[9];
  932. ExtData.lpWidths = (WORD FAR *)&lpMR->rdParm[9+((ExtData.cch+1)/2)];
  933. lpStuff = (LPSTR)&ExtData;
  934. }
  935. #endif
  936. Escape(hdc, lpMR->rdParm[0], lpMR->rdParm[1], lpStuff, (LPSTR)0);
  937. }
  938. }
  939. break;
  940. case (META_FRAMEREGION & 255):
  941. if((hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]])
  942. && (hBrush = lpHandleTable->objectHandle[lpMR->rdParm[1]]))
  943. FrameRgn(hdc, hRgn, hBrush, lpMR->rdParm[3], lpMR->rdParm[2]);
  944. break;
  945. case (META_PAINTREGION & 255):
  946. if(hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]])
  947. PaintRgn(hdc, hRgn);
  948. break;
  949. case (META_INVERTREGION & 255):
  950. if(hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]])
  951. InvertRgn(hdc, hRgn);
  952. break;
  953. case (META_FILLREGION & 255):
  954. if((hRgn = lpHandleTable->objectHandle[lpMR->rdParm[0]])
  955. && (hBrush = lpHandleTable->objectHandle[lpMR->rdParm[1]]))
  956. FillRgn(hdc, hRgn, hBrush);
  957. break;
  958. #ifdef DEADCODE
  959. #ifdef GDI104
  960. case (META_DRAWTEXT & 255):
  961. MFDrawText(hdc, (LPPOINT)&lpMR->rdParm[6], lpMR->rdParm[1], (LPPOINT)&lpMR->rdParm[2], lpMR->rdParm[0]);
  962. break;
  963. #endif
  964. #endif
  965. /*
  966. *** in win2, METACREATEREGION records contained an entire region object,
  967. *** including the full header. this header changed in win3.
  968. ***
  969. *** to remain compatible, the region records will be saved with the
  970. *** win2 header. here we read a win2 header with region, and actually
  971. *** create a win3 header with same region internals
  972. */
  973. case (META_CREATEREGION & 255):
  974. {
  975. #if 0 //!!!!!
  976. HANDLE hRgn;
  977. WORD *pRgn;
  978. WORD iChar;
  979. LPWORD *lpTemp;
  980. iChar = lpMR->rdSize*2 - sizeof(WIN2OBJHEAD) - RECHDRSIZE;
  981. if (hRgn = LocalAlloc(LMEM_ZEROINIT, iChar + sizeof(ILOBJHEAD)))
  982. {
  983. pRgn = (WORD *)Lock IT(hRgn);
  984. *((WIN2OBJHEAD *)pRgn) = *((WIN2OBJHEAD FAR *)&lpMR->rdParm[0]);
  985. ((ILOBJHEAD *)pRgn)->ilObjMetaList = 0;
  986. lpTemp = (LPWORD)&(lpMR->rdParm[0]);
  987. ((WIN2OBJHEAD FAR *)lpTemp)++;
  988. ((ILOBJHEAD *)pRgn)++; /* --> actual region */
  989. for(i = 0; i < (iChar >> 1) ; i++)
  990. *pRgn++ = *lpTemp++;
  991. pRgn = (WORD *)lock IT(hRgn);
  992. ((PRGN)pRgn)->rgnSize = iChar + sizeof(ILOBJHEAD);
  993. AddToHandleTable(lpHandleTable, hRgn, noObjs);
  994. }
  995. #endif //!!!!!
  996. HANDLE hRgn = NULL;
  997. HANDLE hRgn2 = NULL;
  998. WORD cScans;
  999. WORD cPnts;
  1000. WORD cbIncr;
  1001. LPWIN3REGION lpW3Rgn = (LPWIN3REGION)lpMR->rdParm;
  1002. LPSCAN lpScan = lpW3Rgn->aScans;
  1003. LPWORD lpXs;
  1004. for( cScans=lpW3Rgn->cScans; cScans>0; cScans--)
  1005. {
  1006. // If this is the first scan then hRgn2 IS the region
  1007. // otherwise OR it in
  1008. if( hRgn == NULL )
  1009. {
  1010. // Create the first region in this scan
  1011. hRgn = CreateRectRgn( lpScan->scnPntsX[0], lpScan->scnPntTop,
  1012. lpScan->scnPntsX[1], lpScan->scnPntBottom);
  1013. // Allocate a worker region
  1014. hRgn2 = CreateRectRgn( 1, 1, 2, 2);
  1015. }
  1016. else
  1017. {
  1018. SetRectRgn( hRgn2, lpScan->scnPntsX[0], lpScan->scnPntTop,
  1019. lpScan->scnPntsX[1], lpScan->scnPntBottom );
  1020. CombineRgn( hRgn, hRgn, hRgn2, RGN_OR );
  1021. }
  1022. lpXs = &lpScan->scnPntsX[2];
  1023. // If there are more regions on this scan OR them in
  1024. for(cPnts = (WORD)(lpScan->scnPntCnt-2); cPnts>0; cPnts-=2)
  1025. {
  1026. SetRectRgn( hRgn2, *lpXs++, lpScan->scnPntTop,
  1027. *lpXs++, lpScan->scnPntBottom );
  1028. CombineRgn( hRgn, hRgn, hRgn2, RGN_OR );
  1029. }
  1030. cbIncr = (WORD)sizeof(SCAN) + (WORD)(lpScan->scnPntCnt-2);
  1031. cbIncr = (WORD)sizeof(WORD)*(WORD)(lpScan->scnPntCnt-2);
  1032. cbIncr = (WORD)sizeof(SCAN) + (WORD)sizeof(WORD)*(WORD)(lpScan->scnPntCnt-2);
  1033. cbIncr = (WORD)sizeof(SCAN) + (WORD)(sizeof(WORD)*(lpScan->scnPntCnt-2));
  1034. lpScan = (LPSCAN)((LPBYTE)lpScan + cbIncr);
  1035. }
  1036. if( hRgn2 != NULL )
  1037. DeleteObject( hRgn2 );
  1038. AddToHandleTable(lpHandleTable, hRgn, noObjs);
  1039. }
  1040. break;
  1041. case (META_DELETEOBJECT & 255):
  1042. {
  1043. HANDLE h;
  1044. if (h = lpHandleTable->objectHandle[lpMR->rdParm[0]])
  1045. {
  1046. DeleteObjectPriv(h);
  1047. lpHandleTable->objectHandle[lpMR->rdParm[0]] = NULL;
  1048. }
  1049. }
  1050. break;
  1051. case (META_CREATEPALETTE & 255):
  1052. if (hObject = CreatePalette((LPLOGPALETTE)&lpMR->rdParm[0]))
  1053. AddToHandleTable(lpHandleTable, hObject, noObjs);
  1054. break;
  1055. case (META_SELECTPALETTE & 255):
  1056. if(hPal = lpHandleTable->objectHandle[lpMR->rdParm[0]])
  1057. {
  1058. SelectPalette(hdc, hPal, 0);
  1059. }
  1060. break;
  1061. case (META_REALIZEPALETTE & 255):
  1062. RealizePalette(hdc);
  1063. break;
  1064. case (META_SETPALENTRIES & 255):
  1065. /* we know the palette being set is the current palette */
  1066. SetPaletteEntriesPriv(GetCurrentObject(hdc,OBJ_PALETTE), lpMR->rdParm[0],
  1067. lpMR->rdParm[1], (LPPALETTEENTRY)&lpMR->rdParm[2]);
  1068. break;
  1069. case (META_ANIMATEPALETTE & 255):
  1070. AnimatePalettePriv(GetCurrentObject(hdc,OBJ_PALETTE), lpMR->rdParm[0],
  1071. lpMR->rdParm[1], (LPPALETTEENTRY)&lpMR->rdParm[2]);
  1072. break;
  1073. case (META_RESIZEPALETTE & 255):
  1074. ResizePalettePriv(GetCurrentObject(hdc,OBJ_PALETTE), lpMR->rdParm[0]);
  1075. break;
  1076. case (META_SETDIBTODEV & 255):
  1077. {
  1078. LPBITMAPINFOHEADER lpBitmapInfo;
  1079. WORD ColorSize;
  1080. /* if playing into another metafile, do direct copy */
  1081. if (PlayIntoAMetafile(lpMR, hdc))
  1082. goto DontReallyPlay;
  1083. lpBitmapInfo = (LPBITMAPINFOHEADER)&(lpMR->rdParm[9]);
  1084. if (lpBitmapInfo->biClrUsed)
  1085. {
  1086. ColorSize = ((WORD)lpBitmapInfo->biClrUsed) *
  1087. (WORD)(lpMR->rdParm[0] == DIB_RGB_COLORS ?
  1088. sizeof(RGBQUAD) :
  1089. sizeof(WORD));
  1090. }
  1091. else if (lpBitmapInfo->biBitCount == 24)
  1092. ColorSize = 0;
  1093. else
  1094. ColorSize = (WORD)(1 << lpBitmapInfo->biBitCount) *
  1095. (WORD)(lpMR->rdParm[0] == DIB_RGB_COLORS ?
  1096. sizeof(RGBQUAD) :
  1097. sizeof(WORD));
  1098. ColorSize += sizeof(BITMAPINFOHEADER);
  1099. SetDIBitsToDevice(hdc, lpMR->rdParm[8], lpMR->rdParm[7],
  1100. lpMR->rdParm[6], lpMR->rdParm[5],
  1101. lpMR->rdParm[4], lpMR->rdParm[3],
  1102. lpMR->rdParm[2], lpMR->rdParm[1],
  1103. (BYTE FAR *)(((BYTE FAR *)lpBitmapInfo) + ColorSize),
  1104. (LPBITMAPINFO) lpBitmapInfo,
  1105. lpMR->rdParm[0]);
  1106. DontReallyPlay:;
  1107. }
  1108. break;
  1109. case (META_STRETCHDIB & 255):
  1110. {
  1111. LPBITMAPINFOHEADER lpBitmapInfo;
  1112. WORD ColorSize;
  1113. /* if playing into another metafile, do direct copy */
  1114. if (PlayIntoAMetafile(lpMR, hdc))
  1115. goto DontReallyPlay2;
  1116. lpBitmapInfo = (LPBITMAPINFOHEADER)&(lpMR->rdParm[11]);
  1117. if (lpBitmapInfo->biClrUsed)
  1118. {
  1119. ColorSize = ((WORD)lpBitmapInfo->biClrUsed) *
  1120. (WORD)(lpMR->rdParm[2] == DIB_RGB_COLORS ?
  1121. sizeof(RGBQUAD) :
  1122. sizeof(WORD));
  1123. }
  1124. else if (lpBitmapInfo->biBitCount == 24)
  1125. ColorSize = 0;
  1126. else
  1127. ColorSize = (WORD)(1 << lpBitmapInfo->biBitCount) *
  1128. (WORD)(lpMR->rdParm[2] == DIB_RGB_COLORS ?
  1129. sizeof(RGBQUAD) :
  1130. sizeof(WORD));
  1131. ColorSize += sizeof(BITMAPINFOHEADER);
  1132. StretchDIBits(hdc, lpMR->rdParm[10], lpMR->rdParm[9],
  1133. lpMR->rdParm[8], lpMR->rdParm[7],
  1134. lpMR->rdParm[6], lpMR->rdParm[5],
  1135. lpMR->rdParm[4], lpMR->rdParm[3],
  1136. (LPBYTE)(((BYTE FAR *)lpBitmapInfo) + ColorSize),
  1137. (LPBITMAPINFO) lpBitmapInfo,
  1138. lpMR->rdParm[2],
  1139. MAKELONG(lpMR->rdParm[1], lpMR->rdParm[0]));
  1140. DontReallyPlay2:;
  1141. }
  1142. break;
  1143. // Function that have new parameters on WIN32
  1144. // Or have DWORDs that stayed DWORDs; all other INTs to DWORDs
  1145. #ifdef WIN32
  1146. case (META_MOVETO & 255):
  1147. MoveTo( hdc, (long)lpMR->rdParm[1], (long)lpMR->rdParm[0], NULL );
  1148. break;
  1149. case (META_RESTOREDC & 255):
  1150. RestoreDC( hdc, (long)(signed short)lpMR->rdParm[0] );
  1151. break;
  1152. case (META_SETBKCOLOR & 255):
  1153. SetBkColor( hdc, (UINT)*((LPDWORD)lpMR->rdParm) );
  1154. break;
  1155. case (META_SETTEXTCOLOR & 255):
  1156. SetTextColor( hdc, (UINT)*((LPDWORD)lpMR->rdParm) );
  1157. break;
  1158. case (META_SETPIXEL & 255):
  1159. SetPixel( hdc, (UINT)lpMR->rdParm[3], (UINT)lpMR->rdParm[2],
  1160. (UINT)*((LPDWORD)lpMR->rdParm) );
  1161. break;
  1162. case (META_SETMAPPERFLAGS & 255):
  1163. SetMapperFlags( hdc, (UINT)*((LPDWORD)lpMR->rdParm) );
  1164. break;
  1165. case (META_FLOODFILL & 255):
  1166. FloodFill( hdc, (UINT)lpMR->rdParm[3], (UINT)lpMR->rdParm[2],
  1167. (UINT)*((LPDWORD)lpMR->rdParm) );
  1168. break;
  1169. case (META_EXTFLOODFILL & 255):
  1170. ExtFloodFill( hdc, (UINT)lpMR->rdParm[4], (UINT)lpMR->rdParm[3],
  1171. (UINT)*((LPDWORD)&lpMR->rdParm[1]), (UINT)lpMR->rdParm[0] );
  1172. break;
  1173. // These puppies all got a new NULL and have only two parameters and a DC.
  1174. case (META_SETWINDOWORG & 255):
  1175. case (META_SETWINDOWEXT & 255):
  1176. case (META_SETVIEWPORTORG & 255):
  1177. case (META_SETVIEWPORTEXT & 255):
  1178. case (META_OFFSETWINDOWORG & 255):
  1179. case (META_SCALEWINDOWEXT & 255):
  1180. case (META_OFFSETVIEWPORTORG & 255):
  1181. case (META_SCALEVIEWPORTEXT & 255):
  1182. {
  1183. FARPROC lpProc;
  1184. ASSERTGDI((magic&0x00ff) <= MAX_META_DISPATCH, "Unknown function to dispatch1");
  1185. lpProc = alpfnMetaFunc[magic&0x00ff];
  1186. ASSERTGDI( lpProc != (FARPROC)NULL, "function not in dispatch table1 ");
  1187. if (lpProc != (FARPROC)NULL)
  1188. (*lpProc)(hdc, (long)(short)lpMR->rdParm[1], (long)(short)lpMR->rdParm[0], NULL );
  1189. }
  1190. break;
  1191. #endif // WIN32
  1192. default:
  1193. {
  1194. FARPROC lpProc;
  1195. signed short *pshort;
  1196. ASSERTGDI((magic&0x00ff) <= MAX_META_DISPATCH, "Unknown function to dispatch");
  1197. lpProc = alpfnMetaFunc[magic&0x00ff];
  1198. ASSERTGDI( (lpProc != (FARPROC)NULL) || (magic == META_SETRELABS), "function not in dispatch table");
  1199. if ((lpProc == (FARPROC)NULL))
  1200. return;
  1201. // Switch to the corresponding dispatcher by number of parameters
  1202. // The number of parameters in the dispatch number does not include the DC.
  1203. switch (magic >> 8)
  1204. {
  1205. typedef int (FAR PASCAL *META1PROC)(HDC);
  1206. typedef int (FAR PASCAL *META2PROC)(HDC, int);
  1207. typedef int (FAR PASCAL *META3PROC)(HDC, int, int);
  1208. typedef int (FAR PASCAL *META4PROC)(HDC, int, int, int);
  1209. typedef int (FAR PASCAL *META5PROC)(HDC, int, int, int, int);
  1210. typedef int (FAR PASCAL *META6PROC)(HDC, int, int, int, int, int);
  1211. typedef int (FAR PASCAL *META7PROC)(HDC, int, int, int, int, int, int);
  1212. typedef int (FAR PASCAL *META9PROC)(HDC, int, int, int, int, int, int, int, int);
  1213. case 0:
  1214. (*((META1PROC)lpProc))(hdc);
  1215. break;
  1216. case 1:
  1217. (*((META2PROC)lpProc))(hdc,lpMR->rdParm[0]);
  1218. break;
  1219. case 2:
  1220. (*((META3PROC)lpProc))(hdc,lpMR->rdParm[1],lpMR->rdParm[0]);
  1221. break;
  1222. case 3:
  1223. (*((META4PROC)lpProc))(hdc,lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]);
  1224. break;
  1225. case 4:
  1226. (*((META5PROC)lpProc))(hdc,lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]);
  1227. break;
  1228. case 5:
  1229. (*((META6PROC)lpProc))(hdc,lpMR->rdParm[4],lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]);
  1230. break;
  1231. case 6:
  1232. (*((META7PROC)lpProc))(hdc,lpMR->rdParm[5],lpMR->rdParm[4],lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]);
  1233. break;
  1234. case 8:
  1235. (*((META9PROC)lpProc))(hdc,lpMR->rdParm[7],lpMR->rdParm[6],lpMR->rdParm[5],lpMR->rdParm[4],lpMR->rdParm[3],lpMR->rdParm[2],lpMR->rdParm[1],lpMR->rdParm[0]);
  1236. break;
  1237. default:
  1238. ASSERTGDI( FALSE, "No dispatch for this count of args");
  1239. break;
  1240. }
  1241. }
  1242. break;
  1243. }
  1244. #ifndef WIN32
  1245. if (bExtraSel)
  1246. FreeSelector(HIWORD(lpMR));
  1247. #endif // WIN32
  1248. }
  1249. #endif // this is going to gdi.dll
  1250. /****************************** Internal Function **************************\
  1251. * AddToHandleTable
  1252. *
  1253. * Adds an object to the metafile table of objects
  1254. *
  1255. *
  1256. \***************************************************************************/
  1257. VOID INTERNAL AddToHandleTable(LPHANDLETABLE lpHandleTable, HANDLE hObject, WORD noObjs)
  1258. {
  1259. WORD i;
  1260. GdiLogFunc3( " AddToHandleTable");
  1261. /* linear search through table for first open slot */
  1262. for (i = 0; ((lpHandleTable->objectHandle[i] != NULL) && (i < noObjs));
  1263. ++i);
  1264. if (i < noObjs) /* ok index */
  1265. lpHandleTable->objectHandle[i] = hObject;
  1266. else
  1267. {
  1268. ASSERTGDI( 0, "Too many objects in table");
  1269. FatalExit(METAEXITCODE); /* Why can't we store the handle? */
  1270. }
  1271. }
  1272. /****************************** Internal Function **************************\
  1273. * GetFileNumber
  1274. *
  1275. * Returns the DOS file number for a metafiles file
  1276. * -1 if failure
  1277. *
  1278. \***************************************************************************/
  1279. UINT INTERNAL GetFileNumber(LPMETAFILE lpMF)
  1280. {
  1281. int fileNumber;
  1282. GdiLogFunc3( " GetFileNumber");
  1283. if (!(fileNumber = lpMF->MetaFileNumber))
  1284. {
  1285. if ((fileNumber = OpenFile((LPSTR) lpMF->MetaFileBuffer.szPathName,
  1286. (LPOFSTRUCT) &(lpMF->MetaFileBuffer),
  1287. (WORD)OF_PROMPT | OF_REOPEN | OF_READ)
  1288. ) != -1)
  1289. {
  1290. _llseek(fileNumber, (long)lpMF->MetaFilePosition, 0);
  1291. /* need to update MetaFileNumber for floppy files -- amitc */
  1292. lpMF->MetaFileNumber = fileNumber ;
  1293. }
  1294. }
  1295. return fileNumber;
  1296. }
  1297. #if 0
  1298. /****************************** Internal Function **************************\
  1299. * IsValidMetaFile(HANDLE hMetaData)
  1300. *
  1301. * Validates a metafile
  1302. *
  1303. * Returns TRUE iff hMetaData is a valid metafile
  1304. *
  1305. \***************************************************************************/
  1306. BOOL GDIENTRY IsValidMetaFile(HANDLE hMetaData)
  1307. {
  1308. LPMETADATA lpMetaData;
  1309. BOOL status = FALSE;
  1310. GdiLogFunc3( " IsValidMetaFile");
  1311. /* if this is a valid metafile we will save the version in a global variable */
  1312. if (hMetaData && (lpMetaData = (LPMETADATA) GlobalLock(hMetaData)))
  1313. {
  1314. status = (
  1315. (lpMetaData->dataHeader.mtType == MEMORYMETAFILE ||
  1316. lpMetaData->dataHeader.mtType == DISKMETAFILE) &&
  1317. (lpMetaData->dataHeader.mtHeaderSize == HEADERSIZE) &&
  1318. ((lpMetaData->dataHeader.mtVersion ==METAVERSION) ||
  1319. (lpMetaData->dataHeader.mtVersion ==METAVERSION100))
  1320. );
  1321. GlobalUnlock(hMetaData);
  1322. }
  1323. return status;
  1324. }
  1325. #endif
  1326. #define INITIALBUFFERSIZE 16384
  1327. /****************************** Internal Function **************************\
  1328. *
  1329. * AllocBuffer - Allocates a buffer as "large" as possible
  1330. *
  1331. \***************************************************************************/
  1332. HANDLE INTERNAL AllocBuffer(LPWORD piBufferSize)
  1333. {
  1334. WORD iCurBufferSize = INITIALBUFFERSIZE;
  1335. HANDLE hBuffer;
  1336. GdiLogFunc3( " AllocBuffer");
  1337. while (!(hBuffer = GlobalAlloc(GMEM_MOVEABLE |
  1338. GMEM_NODISCARD, (LONG) iCurBufferSize))
  1339. && iCurBufferSize)
  1340. iCurBufferSize >>= 1;
  1341. *piBufferSize = iCurBufferSize;
  1342. return (iCurBufferSize) ? hBuffer : NULL;
  1343. }
  1344. /****************************** Internal Function **************************\
  1345. * CreateBitmapForDC (HDC hMemDC, LPBITMAPINFOHEADER lpDIBInfo)
  1346. *
  1347. * This routine takes a memory device context and a DIB bitmap, creates a
  1348. * compatible bitmap for the DC and fills it with the bits from the DIB (co-
  1349. * -nverting to the device dependent format). The pointer to the DIB bits
  1350. * start immediately after the color table in the INFO header. **
  1351. * **
  1352. * The routine returns the handle to the bitmap with the bits filled in if
  1353. * everything goes well else it returns NULL. **
  1354. \***************************************************************************/
  1355. HANDLE INTERNAL CreateBitmapForDC (HDC hMemDC, LPBITMAPINFOHEADER lpDIBInfo)
  1356. {
  1357. HBITMAP hBitmap ;
  1358. LPBYTE lpDIBits ;
  1359. GdiLogFunc3( " CreateBitmapForDC");
  1360. /* preserve monochrome if it started out as monochrome
  1361. ** and check for REAL Black&white monochrome as opposed
  1362. ** to a 2-color DIB
  1363. */
  1364. if (IsDIBBlackAndWhite(lpDIBInfo))
  1365. hBitmap = CreateBitmap ((WORD)lpDIBInfo->biWidth,
  1366. (WORD)lpDIBInfo->biHeight,
  1367. 1, 1, (LPBYTE) NULL);
  1368. else
  1369. /* otherwise, make a compatible bitmap */
  1370. hBitmap = CreateCompatibleBitmap (hMemDC,
  1371. (WORD)lpDIBInfo->biWidth,
  1372. (WORD)lpDIBInfo->biHeight);
  1373. if (!hBitmap)
  1374. goto CreateBitmapForDCErr ;
  1375. /* take a pointer past the header of the DIB, to the start of the color
  1376. table */
  1377. lpDIBits = (LPBYTE) lpDIBInfo + sizeof (BITMAPINFOHEADER) ;
  1378. /* take the pointer past the color table */
  1379. lpDIBits += GetSizeOfColorTable (lpDIBInfo) ;
  1380. /* get the bits from the DIB into the Bitmap */
  1381. if (!SetDIBits (hMemDC, hBitmap, 0, (WORD)lpDIBInfo->biHeight,
  1382. lpDIBits, (LPBITMAPINFO)lpDIBInfo, 0))
  1383. {
  1384. DeleteObject(hBitmap);
  1385. goto CreateBitmapForDCErr ;
  1386. }
  1387. /* return success */
  1388. return (hBitmap) ;
  1389. CreateBitmapForDCErr:
  1390. /* returm failure for function */
  1391. return (NULL) ;
  1392. }
  1393. /****************************** Internal Function **************************\
  1394. * GetSizeOfColorTable (LPBITMAPINFOHEADER lpDIBInfo)
  1395. *
  1396. * Returns the number of bytes in the color table for the giving info header
  1397. *
  1398. \***************************************************************************/
  1399. WORD INTERNAL GetSizeOfColorTable (LPBITMAPINFOHEADER lpDIBInfo)
  1400. {
  1401. GdiLogFunc3( "GetSizeOfColorTable");
  1402. if (lpDIBInfo->biClrUsed)
  1403. return((WORD)lpDIBInfo->biClrUsed * (WORD)sizeof(RGBQUAD));
  1404. else
  1405. {
  1406. switch (lpDIBInfo->biBitCount)
  1407. {
  1408. case 1:
  1409. return (2 * sizeof (RGBQUAD)) ;
  1410. break ;
  1411. case 4:
  1412. return (16 * sizeof (RGBQUAD)) ;
  1413. break ;
  1414. case 8:
  1415. return (256 * sizeof (RGBQUAD)) ;
  1416. break ;
  1417. default:
  1418. return (0) ;
  1419. break ;
  1420. }
  1421. }
  1422. }
  1423. #if 0 // this is going to gdi.dll
  1424. /***************************** Public Function ****************************\
  1425. * BOOL APIENTRY DeleteMetaFile(hmf)
  1426. *
  1427. * Frees a metafile handle.
  1428. *
  1429. * Effects:
  1430. *
  1431. \***************************************************************************/
  1432. BOOL GDIENTRY DeleteMetaFile(HMETAFILE hmf)
  1433. {
  1434. GdiLogFunc("DeleteMetaFile");
  1435. GlobalFree(hmf);
  1436. return(TRUE);
  1437. }
  1438. /***************************** Public Function ****************************\
  1439. * HMETAFILE APIENTRY GetMetaFile(pzFilename)
  1440. *
  1441. * Returns a metafile handle for a disk based metafile.
  1442. *
  1443. * Effects:
  1444. *
  1445. * History:
  1446. * Sat 14-Oct-1989 14:21:37 -by- Paul Klingler [paulk]
  1447. * Wrote it.
  1448. \***************************************************************************/
  1449. HMETAFILE GDIENTRY GetMetaFile(LPSTR pzFilename)
  1450. {
  1451. BOOL status=FALSE;
  1452. UINT cBytes;
  1453. int file;
  1454. HMETAFILE hmf;
  1455. LPMETAFILE lpmf;
  1456. GdiLogFunc("GetMetaFile");
  1457. // Allocate the Metafile
  1458. if(hmf = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE,(DWORD)sizeof(METAFILE)))
  1459. {
  1460. lpmf = (LPMETAFILE)GlobalLock(hmf);
  1461. // Make sure the file Exists
  1462. if((file = OpenFile(pzFilename,
  1463. &(lpmf->MetaFileBuffer),
  1464. (WORD)OF_PROMPT | OF_EXIST)) == -1L)
  1465. {
  1466. ASSERTGDI( FALSE, "GetMetaFile: Metafile does not exist");
  1467. goto exitGetMetaFile;
  1468. }
  1469. // Open the file
  1470. if((file = OpenFile(pzFilename,
  1471. &(lpmf->MetaFileBuffer),
  1472. (WORD)OF_PROMPT | OF_REOPEN | OF_READWRITE)) == -1)
  1473. {
  1474. ASSERTGDI( FALSE, "GetMetaFile: Unable to open Metafile");
  1475. goto exitGetMetaFile;
  1476. }
  1477. cBytes = (UINT)_lread(file,(LPSTR)(&(lpmf->MetaFileHeader)),sizeof(METAHEADER));
  1478. // Check for an Aldus header
  1479. if (*((LPDWORD)&(lpmf->MetaFileHeader)) == 0x9AC6CDD7)
  1480. {
  1481. _llseek( file, 22, 0);
  1482. cBytes = (UINT)_lread(file,(LPSTR)(&(lpmf->MetaFileHeader)),sizeof(METAHEADER));
  1483. }
  1484. _lclose(file);
  1485. // Validate the metafile
  1486. if(cBytes == sizeof(METAHEADER))
  1487. {
  1488. lpmf->MetaFileHeader.mtType = DISKMETAFILE;
  1489. status = TRUE;
  1490. }
  1491. exitGetMetaFile:
  1492. GlobalUnlock(hmf);
  1493. }
  1494. if(status == FALSE)
  1495. {
  1496. GlobalFree(hmf);
  1497. hmf = NULL;
  1498. }
  1499. return(hmf);
  1500. }
  1501. #endif // this is going to gdi.dll
  1502. #ifdef WIN32
  1503. #undef GetViewportExt
  1504. DWORD GetViewportExt32(HDC hdc)
  1505. {
  1506. SIZE sz;
  1507. GetViewportExt( hdc, &sz );
  1508. return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy)));
  1509. }
  1510. #undef GetWindowExt
  1511. DWORD GetWindowExt32(HDC hdc)
  1512. {
  1513. SIZE sz;
  1514. GetWindowExt( hdc, &sz );
  1515. return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy)));
  1516. }
  1517. #undef SetViewportExt
  1518. DWORD SetViewportExt32(HDC hdc, UINT x, UINT y)
  1519. {
  1520. SIZE sz;
  1521. SetViewportExt( hdc, x, y, &sz );
  1522. return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy)));
  1523. }
  1524. #undef SetWindowExt
  1525. DWORD SetWindowExt32(HDC hdc, UINT x, UINT y)
  1526. {
  1527. SIZE sz;
  1528. SetWindowExt( hdc, x, y, &sz );
  1529. return(MAKELONG(LOWORD(sz.cx),LOWORD(sz.cy)));
  1530. }
  1531. /* Convert WORD arrays into DWORDs */
  1532. LPINT ConvertInts( signed short * pWord, UINT cWords )
  1533. {
  1534. UINT ii;
  1535. LPINT pInt;
  1536. pInt = (LPINT)LocalAlloc( LMEM_FIXED, cWords * sizeof(UINT));
  1537. for( ii=0; ii<cWords; ii++)
  1538. {
  1539. pInt[ii] = (long)(signed)pWord[ii];
  1540. }
  1541. return(pInt);
  1542. }
  1543. #endif // WIN32