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.

1477 lines
51 KiB

  1. /*****************************************************************************
  2. *
  3. * objects - Entry points for Win32 to Win 16 converter
  4. *
  5. * Date: 7/1/91
  6. * Author: Jeffrey Newman (c-jeffn)
  7. *
  8. * Copyright 1991 Microsoft Corp
  9. *
  10. *
  11. * 14-Jan-1992
  12. * Jeffrey Newman
  13. *
  14. * CR1: 14-Jan-1992 - this entire comment and the design that it
  15. * specifies.
  16. *
  17. * The Object system in mf3216.
  18. *
  19. * Overview
  20. *
  21. * The Win32 objects (represented by object handle indicies) must be
  22. * mapped to Win16 objects (also represented by object handle indices).
  23. * Win32 uses stock objects, Win16 does not. MF3216 uses a scheme
  24. * for lazy stock object creation. Through lazy stock object creation
  25. * no unused objects will be emitted into the Win16 metafile.
  26. *
  27. * Objects in a Win16 metafile are maintained in an Object Table. The
  28. * object table is not recorded in the Win16 metafile. It is created at
  29. * play-time. Each entry in the Win16-Object-Table is called a slot.
  30. * Slots are allocated one per object. If an object is deleted then the
  31. * slot becomes available for the next object created. The first object-
  32. * slot, starting from 0, in a linear search, that is available will be
  33. * used to hold the next create object request.
  34. *
  35. * Objects in either a Win32 or a Win16 metafile are represented as an
  36. * index into the Object Table. Every object created must occupy
  37. * the same slot at play-time that it would have occupied at record-time.
  38. *
  39. * Win32 objects have an object ID (index in the handle table) recorded
  40. * with them. Win16 objects do not.
  41. *
  42. * Data Structures
  43. *
  44. * There are two primary data structures used in the translation of
  45. * Win32 objects to Win16 objects. Both of them are dynamically
  46. * allocated arrays. The size of these arrays are determined by
  47. * estimating the number of objects required in the Win16 metafile from
  48. * the size of the handle table used in the Win32 metafile. The size of
  49. * the handle table is recorded in the Win32 metafile header.
  50. *
  51. * The data structure piW16ObjectHandleSlotStatus is used to represent
  52. * the status of the Win16 handle table as it would appear at any point
  53. * during the Win16 metafile playback process. A slot is either in
  54. * use or free.
  55. *
  56. * The data structure piW32ToW16ObjectMap is a translation table
  57. * from the Win32 object indicies to the Win16 object indicies.
  58. * The position in the array (aka the index into the array) is the
  59. * Win32 handle. The value in this entry is the Win16 slot number
  60. * for the handle.
  61. *
  62. * The first 16 entries in piW32ToW16ObjectMap array are used for the
  63. * stock objects.
  64. *
  65. * Support Routines
  66. *
  67. * bInitHandleTableManager
  68. *
  69. * 1] Allocate memory for pW16ObjHndlSlotStatus and
  70. * piW32ToW16ObjectMap arrays.
  71. *
  72. * 2] Initialize pW16ObjHndlSlotStatus and
  73. * piW32ToW16ObjectMap to empty and UNMAPPED respectively.
  74. *
  75. * 3] Returns a TRUE if there were no problems with the
  76. * initialization, FALSE if anything went wrong.
  77. *
  78. * 4] It is expected that this routie will be called once from
  79. * the entry level routine when translation is first started.
  80. *
  81. * iNormalizeHandle
  82. *
  83. * 1] The idea behind this routine is to isolate the handling
  84. * of stock object handles to one place.
  85. *
  86. * 2] Input will be a Win32 handle index, either stock or a
  87. * standard object.
  88. *
  89. * 3] Output will be the index of the entry in the
  90. * piW32ToW16ObjectMap table that corresponds to the W32
  91. * handle. If an error is detected -1 is returned.
  92. *
  93. * 4] All the stock objects will be between the range of 0
  94. * and LAST_STOCK, and all the non-stock objects will be
  95. * greater than LAST_STOCK.
  96. *
  97. * iGetW16ObjectHandleSlot
  98. *
  99. * 1] This routine searches the pW16ObjHndlSlotStatus array
  100. * looking for the first available open slot.
  101. *
  102. * 2] Mark the slot found as to its intended use.
  103. *
  104. * 3] Returns the first open slot if found, else return -1.
  105. *
  106. * 4] In essence this routine mimics the actions of the
  107. * Win16 play-time handle allocation system, in either
  108. * Win3.0 or Win3.1
  109. *
  110. * 5] We also keep track of the max object count here.
  111. *
  112. * iAllocateW16Handle
  113. *
  114. * 1] This routine actually does the handle allocation.
  115. *
  116. * 2] It sets the entry in pW16ObjHndlSlotStatus array
  117. * for the slot allocated by iGetW16ObjectHandleSlot to
  118. * an "in-use" status (for the intended use).
  119. *
  120. * 3] It returns a ihW16 (an index handle to the Win16 handle
  121. * table, aka the Win16 handle slot number).
  122. *
  123. * iValidateHandle
  124. *
  125. * 1] This routine does a lot more than validate a Win32 handle.
  126. * It does some limited error checking on the Win32 handle,
  127. * to make sure its within a reasonable range. Then if a
  128. * Win16 handle table slot has already been allocated for
  129. * this Win32 handle it will return the Win16 handle that
  130. * was previously allocated. Alternatively, if a Win16
  131. * handle has not been previously allocated for a Win32
  132. * STOCK handle it will allocate a W16 handle and return the
  133. * Win16 handle. This function is called by FillRgn, FrameRgn
  134. * and SelectObject to allow lazy allocation of stock objects.
  135. *
  136. * 2] Input is a Win32 handle, either a stock or a non-stock
  137. * handle.
  138. *
  139. * 3] Output is a Win16 handle, this is the value in the
  140. * Win32-index of the piW32ToW16ObjectMap. If a stock object
  141. * does not exist, it will create one.
  142. *
  143. * 4] If there is an error a -1 is returned.
  144. *
  145. * Doer Routines
  146. *
  147. * All the Doers return a bool. TRUE if everything went OK.
  148. * FALSE if there were any problems.
  149. *
  150. * NOTE: The Doers that create an object actually must do
  151. * quite a bit of work to translate the object's prameters.
  152. * This is in addition to managing the handle table. The
  153. * work outlined below just deals with the management of the
  154. * handle table.
  155. *
  156. * DoSelectObject
  157. *
  158. * 1] For stock objects this is the workhorse routine.
  159. *
  160. * 2] For normal, non-stock, objects this routine will verify
  161. * that an object has been created for this Win32 object-index.
  162. * Then it will emit a Win16SelectObject metafile record.
  163. *
  164. * 3] For stock objects things get a little more complicated.
  165. * First this routine must make sure a Win16 object has been
  166. * created for this stock object. If a Win16 object has not
  167. * been created yet, then it will be. After a Win16 object
  168. * is created a Win16SelectObject record will be emitted for
  169. * the object.
  170. *
  171. * DoDeleteObject
  172. *
  173. * 1] The object handle is checked for reasonable limits.
  174. * We will also make sure that the Win16 slot has a handle
  175. * allocated to it. If it does not then we will return an
  176. * error.
  177. *
  178. * 2] If this is a stock object we fail and return an error.
  179. *
  180. * 3] If this is a non-stock object we emit a Win16DeleteObject
  181. * record. Then we set pW16ObjHndlSlotStatus to
  182. * indicate that this slot is available. We also set
  183. * piW32ToW16ObjectMap to -1 (UNMAPPED).
  184. *
  185. * DoCreatePen
  186. * DoExtCreatePen
  187. * DoCreateBrushIndirect
  188. * DoCreateMonoBrush
  189. * DoCreateDIBPatternBrush
  190. * DoExtCreateFont
  191. *
  192. * 1] Make sure the Win32 handle is not already being used
  193. * for something else. If it is return an error.
  194. *
  195. * 2] Validate the handle for this Object. This will return
  196. * a Win16 object table index (actually a slot number).
  197. * We really don't care what the slot number is as long
  198. * as we got one. DoDeleteObject and DoSelectObject always
  199. * refer to handles by their Win32 object indicies, and there
  200. * is no place else where used.
  201. *
  202. * 3] Emit a Win16CreateObject metafile record.
  203. *
  204. *
  205. * Special Routines
  206. *
  207. * bCommonRegionCode
  208. * Need to list the bitblt routines that use handles also
  209. *
  210. * 1] These routines just need to create objects in the Win16
  211. * metafile. There are no corresponding objects in the Win32
  212. * metafile.
  213. *
  214. * 2] Allocate a Win16 handle.
  215. *
  216. * 3] Use the object as needed. This includes emitting a
  217. * region or bitmap object into the Win16 metafile.
  218. *
  219. * 4] De-allocate the object. This include emitting a
  220. * DeleteObject record.
  221. *
  222. * CR1
  223. * Paths require the current pen to selected into the helperDC.
  224. * In order to keep track of create, select, & delete of the pen
  225. * object we will add an extra field to the W16ObjectHandleSlotStatus
  226. * array entries. This new field will contain either a NULL handle
  227. * or a valid Win32 handle. Currently only pens need to be selected
  228. * into the helper DC for paths, so they are the only objects whose
  229. * W32 handle field is not NULL.
  230. *
  231. *****************************************************************************/
  232. #include "precomp.h"
  233. #pragma hdrstop
  234. #define ABS(A) ((A) < 0 ? (-(A)) : (A))
  235. // Stock objects Name Stock
  236. // Object
  237. // ID
  238. LOGBRUSH albStock[] = {
  239. {BS_SOLID, 0x0FFFFFF, 0}, // White Brush 0
  240. {BS_SOLID, 0x0C0C0C0, 0}, // Ligh Grey Brush 1
  241. {BS_SOLID, 0x0808080, 0}, // Grey Brush 2
  242. {BS_SOLID, 0x0404040, 0}, // Dark Grey Brush 3
  243. {BS_SOLID, 0x0000000, 0}, // Black Brush 4
  244. {BS_HOLLOW, 0x0000000, 0} // Hollow Brush 5
  245. } ;
  246. LOGPEN alpnStock[] = {
  247. {PS_SOLID, 0, 0, 0x0FFFFFF}, // White Pen 6
  248. {PS_SOLID, 0, 0, 0x0000000}, // Black Pen 7
  249. {PS_NULL, 0, 0, 0x0FFFFFF} // Null Pen 8
  250. } ;
  251. // Internal function prototypes.
  252. BOOL bCreateStockObject(PLOCALDC pLocalDC, INT ihw32Norm) ;
  253. BOOL bCreateStockFont(PLOCALDC pLocalDC, INT ihW32) ;
  254. /***************************************************************************
  255. * bInitHandleTableManager - Init the Handle Table Manager.
  256. *
  257. * 1] Allocate memory for pW16ObjHndlSlotStatus and
  258. * piW32ToW16ObjectMap arrays.
  259. *
  260. * 2] Initialize pW16ObjHndlSlotStatus and
  261. * piW32ToW16ObjectMap to empty and UNMAPPED respectively.
  262. *
  263. * 3] Returns a TRUE if there were no problems with the
  264. * initialization, FALSE if anything went wrong.
  265. *
  266. * 4] It is expected that this routie will be called once from
  267. * the entry level routine when translation is first started.
  268. *
  269. **************************************************************************/
  270. BOOL bInitHandleTableManager(PLOCALDC pLocalDC, PENHMETAHEADER pmf32header)
  271. {
  272. BOOL b ;
  273. UINT i ;
  274. b = FALSE ;
  275. // The total number of handles required will be the stock handles
  276. // plus the handles used by the Win32 metafile plus one extra
  277. // for temporary brush used in opaque rectangle in textout.
  278. pLocalDC->cW32ToW16ObjectMap = pmf32header->nHandles + (STOCK_LAST + 1) + 1;
  279. // Allocate storage for the translation map.
  280. i = pLocalDC->cW32ToW16ObjectMap * sizeof(INT) ;
  281. pLocalDC->piW32ToW16ObjectMap = (PINT) LocalAlloc(LMEM_FIXED, i) ;
  282. if (pLocalDC->piW32ToW16ObjectMap == NULL)
  283. goto error_exit ;
  284. // Initialize the W32 to W16 object map to UNMAPPED (-1).
  285. // Since we never will have mapping to -1 we can test for
  286. // -1 in the map to make sure we are not double allocating a slot.
  287. for (i = 0 ; i < pLocalDC->cW32ToW16ObjectMap ; i++)
  288. pLocalDC->piW32ToW16ObjectMap[i] = UNMAPPED ;
  289. // Allocate storage for the slot status tables.
  290. // The number of Win16 object table slot may expand during conversion
  291. // due to temporary bitmaps and regions. It is my educated guess
  292. // that we will never need more than 5 extra slots, because we
  293. // only use a slot for a very short time, then free it. We are
  294. // allocating 256 extra slots in the name of robustness.
  295. // Note that the multi-format comment record may take up some
  296. // of these slots and increase the high water mark for object index.
  297. // We need to expand the table when required.
  298. pLocalDC->cW16ObjHndlSlotStatus = pLocalDC->cW32ToW16ObjectMap + 256 ;
  299. if (pLocalDC->cW16ObjHndlSlotStatus > (UINT) (WORD) MAXWORD)
  300. goto error_exit ; // w16 handle index is only 16-bit
  301. i = pLocalDC->cW16ObjHndlSlotStatus * sizeof(W16OBJHNDLSLOTSTATUS) ;
  302. pLocalDC->pW16ObjHndlSlotStatus
  303. = (PW16OBJHNDLSLOTSTATUS) LocalAlloc(LMEM_FIXED, i) ;
  304. if (pLocalDC->pW16ObjHndlSlotStatus == NULL)
  305. goto error_exit ;
  306. // Initialize the W16ObjectHandleSlotStatus to a state where every
  307. // handle is available.
  308. for (i = 0 ; i < pLocalDC->cW16ObjHndlSlotStatus ; i++)
  309. {
  310. pLocalDC->pW16ObjHndlSlotStatus[i].use = OPEN_AVAILABLE_SLOT ;
  311. pLocalDC->pW16ObjHndlSlotStatus[i].w32Handle = 0 ;
  312. pLocalDC->pW16ObjHndlSlotStatus[i].iXORPassCreation = NOTXORPASS ;
  313. pLocalDC->pW16ObjHndlSlotStatus[i].pbCreatRec = NULL ;
  314. }
  315. // Initialize the pW32hPal palette handle table.
  316. // This table is used to store the W32 palette handles created during
  317. // the conversion.
  318. pLocalDC->cW32hPal = pmf32header->nHandles;
  319. i = pLocalDC->cW32hPal * sizeof(HPALETTE);
  320. pLocalDC->pW32hPal = (HPALETTE *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, i) ;
  321. if (pLocalDC->pW32hPal == NULL)
  322. goto error_exit ;
  323. b = TRUE;
  324. error_exit:
  325. if (!b)
  326. {
  327. if (pLocalDC->piW32ToW16ObjectMap)
  328. {
  329. if (LocalFree(pLocalDC->piW32ToW16ObjectMap))
  330. ASSERTGDI(FALSE, "MF3216: LocalFree failed");
  331. pLocalDC->piW32ToW16ObjectMap = (PINT) NULL;
  332. }
  333. if (pLocalDC->pW16ObjHndlSlotStatus)
  334. {
  335. if (LocalFree(pLocalDC->pW16ObjHndlSlotStatus))
  336. ASSERTGDI(FALSE, "MF3216: LocalFree failed");
  337. pLocalDC->pW16ObjHndlSlotStatus = NULL;
  338. }
  339. }
  340. return(b) ;
  341. }
  342. /***************************************************************************
  343. * bDeleteW16Object - Delete a W16 Object.
  344. *
  345. * This is the routine that is called to Delete a W16 Object that has
  346. * no corresponding W32 object. Region and Bitmaps are two examples.
  347. **************************************************************************/
  348. BOOL bDeleteW16Object(PLOCALDC pLocalDC, INT ihW16)
  349. {
  350. BOOL b ;
  351. ASSERTGDI
  352. (
  353. pLocalDC->pW16ObjHndlSlotStatus[ihW16].use != OPEN_AVAILABLE_SLOT,
  354. "MF3216: bDeleteW16Object, bad use value"
  355. );
  356. // Mark the W16 Slot just freed as available.
  357. pLocalDC->pW16ObjHndlSlotStatus[ihW16].use = OPEN_AVAILABLE_SLOT ;
  358. // Emit a Win16 DeleteOject record for the Object
  359. b = bEmitWin16DeleteObject(pLocalDC, LOWORD(ihW16)) ;
  360. return (b) ;
  361. }
  362. /***************************************************************************
  363. * iGetW16ObjectHandleSlot - return the first W16 open slot in the handle
  364. * table.
  365. *
  366. * 1] This routine searches the pW16ObjHndlSlotStatus array
  367. * looking for the first available open slot.
  368. *
  369. * 2] Mark the slot found as to its intended use.
  370. *
  371. * 3] Returns the first open slot if found, else return -1.
  372. *
  373. * 4] In essence this routine mimics the actions of the
  374. * Win16 play-time handle allocation system, in either
  375. * Win3.0 or Win3.1
  376. *
  377. * 5] We also keep track of the max object count here.
  378. *
  379. **************************************************************************/
  380. INT iGetW16ObjectHandleSlot(PLOCALDC pLocalDC, INT iIntendedUse)
  381. {
  382. BOOL b ;
  383. UINT i ;
  384. b = FALSE ;
  385. // Search for an available slot.
  386. for (i = 0 ; i < pLocalDC->cW16ObjHndlSlotStatus ; i++)
  387. {
  388. if (pLocalDC->pW16ObjHndlSlotStatus[i].use == OPEN_AVAILABLE_SLOT)
  389. {
  390. b = TRUE ;
  391. break ;
  392. }
  393. }
  394. // If a slot was found then mark its intended use.
  395. // Also set the W32 handle that may be associated with this
  396. // W16 handle to NULL. (Meaning no association at this time.)
  397. if (b)
  398. {
  399. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[i].w32Handle == 0,
  400. "MF3216: iGetW16ObjectHandleSlot: w32Handle is not 0");
  401. pLocalDC->pW16ObjHndlSlotStatus[i].use = iIntendedUse ;
  402. pLocalDC->pW16ObjHndlSlotStatus[i].w32Handle = 0 ;
  403. pLocalDC->pW16ObjHndlSlotStatus[i].iXORPassCreation = pLocalDC->iXORPass ;
  404. pLocalDC->pW16ObjHndlSlotStatus[i].pbCreatRec = pLocalDC->pbRecord ;
  405. // Update the number of object counts. This will be used
  406. // when we update the metafile header.
  407. if ((INT) i >= pLocalDC->nObjectHighWaterMark)
  408. pLocalDC->nObjectHighWaterMark = (INT) i;
  409. return((INT) i);
  410. }
  411. else
  412. {
  413. RIPS("MF3216: iGetW16ObjectHandleSlot, Slot not found\n") ;
  414. return(-1) ;
  415. }
  416. }
  417. /***************************************************************************
  418. * iNormalizeHandle
  419. *
  420. * CR1 - this entire routine is part of the handle system redesign.
  421. *
  422. * 1] The idea behind this routine is to isolate the handling
  423. * of stock object handles to one place.
  424. *
  425. * 2] Input will be a Win32 handle index, either stock or a
  426. * standard object.
  427. *
  428. * 3] Output will be the index of the entry in the
  429. * piW32ToW16ObjectMap table that corresponds to the W32
  430. * handle. If an error is detected -1 is returned.
  431. *
  432. * 4] All the stock objects will be between the range of 0
  433. * and LAST_STOCK, and all the non-stock objects will be
  434. * greater than LAST_STOCK.
  435. *
  436. **************************************************************************/
  437. INT iNormalizeHandle(PLOCALDC pLocalDC, INT ihW32)
  438. {
  439. INT ihW32Norm ;
  440. if (ihW32 & ENHMETA_STOCK_OBJECT)
  441. {
  442. ihW32Norm = ihW32 & ~ENHMETA_STOCK_OBJECT ;
  443. if ((UINT) ihW32Norm > STOCK_LAST)
  444. {
  445. RIPS("MF3216: iNormalizeHandle, bad stock object\n") ;
  446. ihW32Norm = -1 ;
  447. }
  448. }
  449. else
  450. {
  451. ihW32Norm = ihW32 + STOCK_LAST + 1 ;
  452. if ((UINT) ihW32Norm >= pLocalDC->cW32ToW16ObjectMap)
  453. {
  454. RIPS("MF3216: iNormalizeHandle, bad standard object\n") ;
  455. ihW32Norm = -1 ;
  456. }
  457. }
  458. return(ihW32Norm) ;
  459. }
  460. /***************************************************************************
  461. * iAllocateW16Handle
  462. *
  463. * CR1 - this entire routine is part of the handle system redesign.
  464. * It is to be called from the object creation routines.
  465. *
  466. * 1] This routine actually does the handle allocation.
  467. *
  468. * 2] It sets the entry in pW16ObjHndlSlotStatus array
  469. * for the slot allocated by iGetW16ObjectHandleSlot to
  470. * an "in-use" status (for the intended use).
  471. *
  472. * 3] It returns a ihW16 (an index handle to the Win16 handle
  473. * table, aka the Win16 handle slot number).
  474. *
  475. **************************************************************************/
  476. INT iAllocateW16Handle(PLOCALDC pLocalDC, INT ihW32, INT iIntendedUse)
  477. {
  478. INT ihW32Norm,
  479. ihW16 ;
  480. // Assume the worst, set up for a failed return code.
  481. ihW16 = -1 ;
  482. // Normalize the handle.
  483. ihW32Norm = iNormalizeHandle(pLocalDC, ihW32) ;
  484. if (ihW32Norm == -1)
  485. goto error_exit ;
  486. // Check for double allocation of a Win32 handle index.
  487. // If we find a double allocation, this would indicate an error
  488. // in the Win32 metafile.
  489. // Error out on this due to the possibility of
  490. // a brush being used for a bitmap, or some other wrong use of a handle.
  491. if (pLocalDC->piW32ToW16ObjectMap[ihW32Norm] != UNMAPPED)
  492. {
  493. RIPS("MF3216: iAllocateW16Handle, Double W32 handle allocation detected\n") ;
  494. goto error_exit ;
  495. }
  496. // Get a slot in the Win16 handle table.
  497. ihW16 = iGetW16ObjectHandleSlot(pLocalDC, iIntendedUse) ;
  498. if (ihW16 == -1)
  499. goto error_exit ;
  500. // Set the W32 to W16 slot mapping
  501. pLocalDC->piW32ToW16ObjectMap[ihW32Norm] = ihW16 ;
  502. error_exit:
  503. return(ihW16) ;
  504. }
  505. /***************************************************************************
  506. * iValidateHandle
  507. *
  508. * CR1 - this entire routine is part of the handle system redesign.
  509. *
  510. * 1] This routine does a lot more than validate a Win32 handle.
  511. * It does some limited error checking on the Win32 handle,
  512. * to make sure its within a reasonable range. Then if a
  513. * Win16 handle table slot has already been allocated for
  514. * this Win32 handle it will return the Win16 handle that
  515. * was previously allocated. Alternatively, if a Win16
  516. * handle has not been previously allocated for a Win32
  517. * STOCK handle it will allocate a W16 handle and return the
  518. * Win16 handle. This function is called by FillRgn, FrameRgn
  519. * and SelectObject to allow lazy allocation of stock objects.
  520. *
  521. * 2] Input is a Win32 handle, either a stock or a non-stock
  522. * handle.
  523. *
  524. * 3] Output is a Win16 handle, this is the value in the
  525. * Win32-index of the piW32ToW16ObjectMap. If a stock object
  526. * does not exist, it will create one.
  527. *
  528. * 4] If there is an error a -1 is returned.
  529. **************************************************************************/
  530. INT iValidateHandle(PLOCALDC pLocalDC, INT ihW32)
  531. {
  532. INT ihW32Norm,
  533. ihW16 ;
  534. // Assume the worst.
  535. ihW16 = -1 ;
  536. // NOTE: Normalizing the W32 handles takes care of checking
  537. // for a reasonable W32 handle value.
  538. ihW32Norm = iNormalizeHandle(pLocalDC, ihW32) ;
  539. if (ihW32Norm == -1)
  540. goto error_exit ;
  541. // Check the W32ToW16 map, to determine if this W32 handle has
  542. // already been allocated a W16 slot.
  543. ihW16 = pLocalDC->piW32ToW16ObjectMap[ihW32Norm] ;
  544. if (ihW16 == UNMAPPED)
  545. {
  546. // There is no mapping from W32 to W16. This implies
  547. // that the object in question does not exist. If this is
  548. // a stock object, then we will create the object at this time.
  549. // Alternatively, if this is a non-stock object then we have an
  550. // error condition.
  551. if ((DWORD) ihW32Norm <= STOCK_LAST)
  552. {
  553. if (bCreateStockObject(pLocalDC, ihW32))
  554. ihW16 = pLocalDC->piW32ToW16ObjectMap[ihW32Norm] ;
  555. else
  556. ihW16 = -1 ;
  557. }
  558. else
  559. {
  560. RIPS("MF3216: iValidateHandle - Unmapped Standard Object\n") ;
  561. ihW16 = -1 ;
  562. }
  563. }
  564. error_exit:
  565. return (ihW16) ;
  566. }
  567. /***************************************************************************
  568. * DoDeleteObject - Win32 to Win16 Metafile Converter Entry Point
  569. *
  570. * CR1 - Most of this routine was rewritten to conform to the new
  571. * objects management system.
  572. *
  573. * 1] The object handle is checked for reasonable limits.
  574. * We will also make sure that the Win16 slot has a handle
  575. * allocated to it. If it does not then we will return an
  576. * error.
  577. *
  578. * 2] If this is a stock object we fail and return an error.
  579. *
  580. * 3] If this is a non-stock object we emit a Win16DeleteObject
  581. * record. Then we set pW16ObjHndlSlotStatus to
  582. * indicate that this slot is available. We also set
  583. * piW32ToW16ObjectMap to -1 (UNMAPPED).
  584. *
  585. * 4] If we are in the first pass of an XOR-ClipPath rendering
  586. * then we verify if this object was created during this pass
  587. * If the object wasn't created during this pass, we will need
  588. * to recreate the object when we start the second pass so that
  589. * any call to SelectObject will return with the proper object
  590. * selected (GillesK)
  591. **************************************************************************/
  592. BOOL WINAPI DoDeleteObject
  593. (
  594. PLOCALDC pLocalDC,
  595. INT ihObject
  596. )
  597. {
  598. BOOL b ;
  599. INT ihW16,
  600. ihW32Norm;
  601. // Assume the worst.
  602. b = FALSE ;
  603. // Normalize the W32 handle.
  604. ihW32Norm = iNormalizeHandle(pLocalDC, ihObject) ;
  605. if (ihW32Norm == -1)
  606. goto error_exit ;
  607. // Make sure we're not deleting a stock object.
  608. if ((DWORD) ihW32Norm <= STOCK_LAST)
  609. {
  610. PUTS("MF3216: DoDeleteObject, attempt to delete a stock object\n") ;
  611. return(TRUE);
  612. }
  613. // If this is a palette, then we do not delete the win16 object.
  614. // We do delete our local version of the palette.
  615. if (pLocalDC->pW32hPal && pLocalDC->pW32hPal[ihObject])
  616. {
  617. b = DeleteObject(pLocalDC->pW32hPal[ihObject]);
  618. pLocalDC->pW32hPal[ihObject] = 0;
  619. if (b == FALSE)
  620. RIPS("MF3216: DoDeleteObject - DeleteObject (hPalette) failed\n") ;
  621. return (b) ;
  622. }
  623. // Map the ihW32 to a ihW16 (object handle table slot).
  624. ihW16 = pLocalDC->piW32ToW16ObjectMap[ihW32Norm] ;
  625. if (ihW16 == UNMAPPED)
  626. {
  627. RIPS("MF3216: DoDeleteObject, attempt to delete a non-existent object\n");
  628. goto error_exit ;
  629. }
  630. // Make sure the object is one that we expect.
  631. // There is no region object or bitmap object in the enhanced metafiles.
  632. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_BRUSH
  633. || pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_PEN
  634. || pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_FONT,
  635. "MF3216: DoDeleteObject, Invalid Object Deletion\n") ;
  636. // If there was a Win32 handle associated with this Win16 handle
  637. // then the w32Handle field of the W16ObjHndlSlotStatus[ihW16]
  638. // entry in the handle slot status array will be non-null. If
  639. // it is non-null then we should delete the Win32 handle at this time.
  640. if (pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle != 0)
  641. {
  642. if (!DeleteObject(pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle))
  643. {
  644. ASSERTGDI(FALSE, "MF3216: DoDeleteObject, DeleteObject failed");
  645. }
  646. pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle = 0 ;
  647. }
  648. if( pLocalDC->iXORPass == DRAWXORPASS && pLocalDC->pW16ObjHndlSlotStatus[ihW16].iXORPassCreation != DRAWXORPASS )
  649. {
  650. // If we delete an object that was created before this pass
  651. // the we need to save the object creation record so that
  652. // we can recreate the object once this pass is over
  653. // We create a linked list of objects that we have to recreate.
  654. PW16RECREATIONSLOT pW16RecreationSlot = (PW16RECREATIONSLOT) LocalAlloc( LMEM_FIXED, sizeof( W16RECREATIONSLOT ) ) ;
  655. if( pW16RecreationSlot == NULL )
  656. goto error_exit ;
  657. pW16RecreationSlot->slot = ihW16 ;
  658. pW16RecreationSlot->pbCreatRec = pLocalDC->pW16ObjHndlSlotStatus[ihW16].pbCreatRec ;
  659. pW16RecreationSlot->pNext = pLocalDC->pW16RecreationSlot ;
  660. pLocalDC->pW16RecreationSlot = pW16RecreationSlot ;
  661. }
  662. // Mark the slot as available.
  663. // And set the map entry for the W32ToW16 map to unmapped.
  664. pLocalDC->pW16ObjHndlSlotStatus[ihW16].use = OPEN_AVAILABLE_SLOT ;
  665. pLocalDC->pW16ObjHndlSlotStatus[ihW16].pbCreatRec = NULL ;
  666. pLocalDC->piW32ToW16ObjectMap[ihW32Norm] = UNMAPPED ;
  667. // Emit the delete drawing order.
  668. b = bEmitWin16DeleteObject(pLocalDC, LOWORD(ihW16)) ;
  669. error_exit:
  670. return (b) ;
  671. }
  672. /***************************************************************************
  673. * DoSelectObject - Win32 to Win16 Metafile Converter Entry Point
  674. *
  675. * CR1 - Major rewrite due to handle system redesign.
  676. *
  677. * DoSelectObject
  678. *
  679. * 1] For stock objects this is the workhorse routine.
  680. *
  681. * 2] For normal, non-stock, objects this routine will verify
  682. * that an object has been created for this Win32 object-index.
  683. * Then it will emit a Win16SelectObject metafile record.
  684. *
  685. * 3] For stock objects things get a little more complicated.
  686. * First this routine must make sure a Win16 object has been
  687. * created for this stock object. If a Win16 object has not
  688. * been created yet, then it will be. After a Win16 object
  689. * is created a Win16SelectObject record will be emitted for
  690. * the object.
  691. **************************************************************************/
  692. BOOL WINAPI DoSelectObject
  693. (
  694. PLOCALDC pLocalDC,
  695. LONG ihObject
  696. )
  697. {
  698. BOOL b ;
  699. INT ihW16;
  700. // Assume the worst.
  701. b = FALSE ;
  702. // Make sure that the W16 object exists before we emit the
  703. // SelectObject record. Stock objects may not have been created
  704. // and iValidateHandle will take care of creating them.
  705. ihW16 = iValidateHandle(pLocalDC, ihObject) ;
  706. if (ihW16 == -1)
  707. goto error_exit ;
  708. // Make sure the object is one that we expect.
  709. // There is no region object or bitmap object in the enhanced metafiles.
  710. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_BRUSH
  711. || pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_PEN
  712. || pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_FONT,
  713. "MF3216: DoSelectObject, Invalid Object Deletion\n") ;
  714. // Remember the currently selected pen. This is used in path and text.
  715. if (pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_PEN)
  716. pLocalDC->lhpn32 = ihObject;
  717. // Remember the currently selected brush. This is used in text.
  718. if (pLocalDC->pW16ObjHndlSlotStatus[ihW16].use == REALIZED_BRUSH)
  719. pLocalDC->lhbr32 = ihObject;
  720. // If there was a Win32 handle associated with this Win16 handle
  721. // then the w32Handle field of the W16ObjHndlSlotStatus[ihW16]
  722. // entry in the handle slot status array will be non-null. If
  723. // it is non-null then we should select the W32 object into the
  724. // helper DC at this time.
  725. if (pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle != 0)
  726. SelectObject(pLocalDC->hdcHelper,
  727. pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle) ;
  728. b = bEmitWin16SelectObject(pLocalDC, LOWORD(ihW16)) ;
  729. error_exit:
  730. return(b) ;
  731. }
  732. /***************************************************************************
  733. * bCreateStockObject
  734. **************************************************************************/
  735. BOOL bCreateStockObject(PLOCALDC pLocalDC, INT ihW32)
  736. {
  737. BOOL b ;
  738. INT i ;
  739. ASSERTGDI((ihW32 & ENHMETA_STOCK_OBJECT) != 0,
  740. "MF3216: bCreateStockObject, invalid stock handle");
  741. switch (ihW32 & ~ENHMETA_STOCK_OBJECT)
  742. {
  743. case WHITE_BRUSH:
  744. case LTGRAY_BRUSH:
  745. case GRAY_BRUSH:
  746. case DKGRAY_BRUSH:
  747. case BLACK_BRUSH:
  748. case NULL_BRUSH:
  749. b = DoCreateBrushIndirect(pLocalDC, ihW32, &albStock[ihW32 & ~ENHMETA_STOCK_OBJECT]) ;
  750. break ;
  751. case WHITE_PEN:
  752. case BLACK_PEN:
  753. case NULL_PEN:
  754. i = (ihW32 & ~ENHMETA_STOCK_OBJECT) - WHITE_PEN ;
  755. b = DoCreatePen(pLocalDC, ihW32, (PLOGPEN) &alpnStock[i]) ;
  756. break ;
  757. case OEM_FIXED_FONT:
  758. case ANSI_FIXED_FONT:
  759. case ANSI_VAR_FONT:
  760. case SYSTEM_FONT:
  761. case DEVICE_DEFAULT_FONT:
  762. case SYSTEM_FIXED_FONT:
  763. case DEFAULT_GUI_FONT:
  764. b = bCreateStockFont(pLocalDC, ihW32) ;
  765. break ;
  766. case DEFAULT_PALETTE:
  767. default:
  768. // Logical palettes are handled in DoSelectPalette and should
  769. // not get here.
  770. RIPS("MF3216: bCreateStockObject - Invalid Stock Object\n") ;
  771. b =FALSE ;
  772. break ;
  773. }
  774. return (b) ;
  775. }
  776. /***************************************************************************
  777. * bCreateStockFont
  778. **************************************************************************/
  779. BOOL bCreateStockFont(PLOCALDC pLocalDC, INT ihW32)
  780. {
  781. BOOL b ;
  782. INT i ;
  783. LOGFONTA LogFontA ;
  784. HANDLE hFont ;
  785. b = FALSE ;
  786. ASSERTGDI((ihW32 & ENHMETA_STOCK_OBJECT) != 0,
  787. "MF3216: bCreateStockObject, invalid stock handle");
  788. // Get a handle to this logfont.
  789. hFont = GetStockObject(ihW32 & ~ENHMETA_STOCK_OBJECT) ;
  790. if (hFont == (HANDLE) 0)
  791. {
  792. RIPS("MF3216: bCreateStockFont, GetStockObject (font) failed\n") ;
  793. goto error_exit ;
  794. }
  795. // Get the logfont data. Assume we get at least one char in the
  796. // facename string.
  797. i = GetObjectA(hFont, sizeof(LOGFONTA), &LogFontA) ;
  798. if (i <= (INT) offsetof(LOGFONTA,lfFaceName[0]))
  799. {
  800. PUTS("MF3216: bCreateStockFont - GetObjectW failed\n") ;
  801. goto error_exit ;
  802. }
  803. // Zero out the remaining logfont structure.
  804. for ( ; i < sizeof(LOGFONTA); i++)
  805. ((PBYTE) &LogFontA)[i] = 0;
  806. // Create a LogFont for this stock font in the Win16 metafile.
  807. b = DoExtCreateFont(pLocalDC,
  808. ihW32,
  809. &LogFontA);
  810. error_exit:
  811. return (b) ;
  812. }
  813. /***************************************************************************
  814. * CreateBrushIndirect - Win32 to Win16 Metafile Converter Entry Point
  815. **************************************************************************/
  816. BOOL WINAPI DoCreateBrushIndirect
  817. (
  818. PLOCALDC pLocalDC,
  819. INT ihBrush,
  820. LPLOGBRUSH lpLogBrush
  821. )
  822. {
  823. WIN16LOGBRUSH Win16LogBrush ;
  824. BOOL b ;
  825. INT ihW16 ;
  826. LOGBRUSH LogBrush ;
  827. b = FALSE ;
  828. // Only 3 brush styles are allowed.
  829. if (lpLogBrush->lbStyle != BS_SOLID
  830. && lpLogBrush->lbStyle != BS_HATCHED
  831. && lpLogBrush->lbStyle != BS_HOLLOW)
  832. goto error_exit ;
  833. // Make a copy of the logical brush.
  834. LogBrush = *lpLogBrush;
  835. // The first 6 hatched styles map directly from Win32 to Win16.
  836. // The remaining hatched brushes are simulated using DIB pattern
  837. // brushes. Note that the background color of a hatched brush
  838. // is the current background color but that of a DIB pattern brush
  839. // is given at create time! We will use the current background color
  840. // in the DIB pattern brush when it is created. As a result, the
  841. // output of these brushes may look different!
  842. if (LogBrush.lbStyle == BS_HATCHED)
  843. {
  844. switch (LogBrush.lbHatch)
  845. {
  846. case HS_HORIZONTAL:
  847. case HS_VERTICAL:
  848. case HS_FDIAGONAL:
  849. case HS_BDIAGONAL:
  850. case HS_CROSS:
  851. case HS_DIAGCROSS:
  852. break;
  853. default:
  854. RIPS("MF3216: Unknown hatched pattern\n");
  855. LogBrush.lbStyle = BS_SOLID;
  856. break;
  857. }
  858. }
  859. // Allocate the W16 handle.
  860. ihW16 = iAllocateW16Handle(pLocalDC, ihBrush, REALIZED_BRUSH);
  861. if (ihW16 == -1)
  862. goto error_exit ;
  863. // Create the w32 brush and store it in the w16 slot table.
  864. // This brush is needed by the helper DC for BitBlt simulations.
  865. pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle
  866. = CreateBrushIndirect(lpLogBrush) ;
  867. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle != 0,
  868. "MF3216: CreateBrushIndirect failed");
  869. // Assign all the Win32 brush attributes to Win16 brush attributes.
  870. Win16LogBrush.lbStyle = (WORD) LogBrush.lbStyle ;
  871. Win16LogBrush.lbColor = LogBrush.lbColor ;
  872. Win16LogBrush.lbHatch = (SHORT) LogBrush.lbHatch ;
  873. // Call the Win16 routine to emit the brush to the metafile.
  874. b = bEmitWin16CreateBrushIndirect(pLocalDC, &Win16LogBrush) ;
  875. error_exit:
  876. return(b) ;
  877. }
  878. /******************************Public*Routine******************************\
  879. * CreateMonoDib
  880. *
  881. * This is the same as CreateBitmap except that the bits are assumed
  882. * to be DWORD aligned and that the scans start from the bottom of the bitmap.
  883. *
  884. * This routine is temporary until CreateDIBitmap supports monochrome bitmaps
  885. *
  886. * History:
  887. * Wed Jul 01 11:02:24 1992 -by- Hock San Lee [hockl]
  888. * Wrote it.
  889. \**************************************************************************/
  890. HBITMAP CreateMonoDib
  891. (
  892. LPBITMAPINFO pbmi,
  893. CONST BYTE * pjBits,
  894. UINT iUsage
  895. )
  896. {
  897. HBITMAP hbm;
  898. ASSERTGDI(pbmi->bmiHeader.biPlanes == 1, "CreateMonoDib: bad biPlanes value");
  899. ASSERTGDI(pbmi->bmiHeader.biBitCount == 1, "CreateMonoDib: bad biBitCount value");
  900. hbm = CreateBitmap((int) pbmi->bmiHeader.biWidth,
  901. (int) pbmi->bmiHeader.biHeight,
  902. (UINT) 1,
  903. (UINT) 1,
  904. (CONST VOID *) NULL);
  905. if (!hbm)
  906. return(hbm);
  907. SetDIBits((HDC) 0, hbm, 0, (UINT) pbmi->bmiHeader.biHeight,
  908. (CONST VOID *) pjBits, pbmi, iUsage);
  909. return(hbm);
  910. }
  911. /***************************************************************************
  912. * CreateMonoBrush - Win32 to Win16 Metafile Converter Entry Point
  913. **************************************************************************/
  914. BOOL WINAPI DoCreateMonoBrush
  915. (
  916. PLOCALDC pLocalDC,
  917. DWORD ihBrush,
  918. PBITMAPINFO pBitmapInfo,
  919. DWORD cbBitmapInfo,
  920. PBYTE pBits,
  921. DWORD cbBits,
  922. DWORD iUsage
  923. )
  924. {
  925. BOOL b ;
  926. INT ihW16;
  927. DWORD ul ;
  928. BYTE pbmi[sizeof(BITMAPINFOHEADER) + 2 * sizeof(RGBQUAD)];
  929. HBITMAP hbm;
  930. b = FALSE ;
  931. // Need to make a copy of the bitmap info header, for a few reasons
  932. // 1] the memory mapped file is write protected.
  933. // 2] the iUsage may be (is) use palatte indicies, and we need
  934. // use RGB colors.
  935. ((PBITMAPINFO) pbmi)->bmiHeader = pBitmapInfo->bmiHeader;
  936. // Need to make sure the iUsage is DIB_RGB_COLORS
  937. // and the palette is initialized to Black and White.
  938. ul = 0 ;
  939. ((PBITMAPINFO) pbmi)->bmiColors[0] = (*((RGBQUAD *) &(ul))) ;
  940. ul = 0x00ffffff ;
  941. ((PBITMAPINFO) pbmi)->bmiColors[1] = (*((RGBQUAD *) &(ul))) ;
  942. // Allocate the W16 handle.
  943. ihW16 = iAllocateW16Handle(pLocalDC, ihBrush, REALIZED_BRUSH);
  944. if (ihW16 == -1)
  945. goto error_exit ;
  946. // Create the w32 brush and store it in the w16 slot table.
  947. // This brush is needed by the helper DC for BitBlt simulations.
  948. if ((hbm = CreateMonoDib
  949. (
  950. pBitmapInfo,
  951. (CONST BYTE *) pBits,
  952. (UINT) iUsage
  953. )
  954. )
  955. )
  956. {
  957. pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle
  958. = CreatePatternBrush(hbm);
  959. if (!DeleteObject(hbm))
  960. ASSERTGDI(FALSE, "MF3216: DoCreateMonoBrush, DeleteObject failed");
  961. }
  962. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle != 0,
  963. "MF3216: CreatePatternBrush failed");
  964. // Call the Win16 routine to emit the brush to the metafile.
  965. b = bEmitWin16CreateDIBPatternBrush(pLocalDC,
  966. (PBITMAPINFO) pbmi,
  967. sizeof(pbmi),
  968. pBits,
  969. cbBits,
  970. (WORD) DIB_RGB_COLORS,
  971. (WORD) BS_PATTERN // Mono brush!
  972. ) ;
  973. error_exit:
  974. return(b) ;
  975. }
  976. /***************************************************************************
  977. * CreateDIPatternBrush - Win32 to Win16 Metafile Converter Entry Point
  978. **************************************************************************/
  979. BOOL WINAPI DoCreateDIBPatternBrush
  980. (
  981. PLOCALDC pLocalDC,
  982. DWORD ihBrush,
  983. PBITMAPINFO pBitmapInfo,
  984. DWORD cbBitmapInfo,
  985. PBYTE pBits,
  986. DWORD cbBits,
  987. DWORD iUsage
  988. )
  989. {
  990. BOOL b;
  991. INT ihW16;
  992. HBITMAP hbm;
  993. PBYTE pBits24;
  994. DWORD cbBits24;
  995. BITMAPINFOHEADER bmih;
  996. hbm = (HBITMAP) 0;
  997. pBits24 = (PBYTE) NULL;
  998. b = FALSE ;
  999. // Allocate the W16 handle.
  1000. ihW16 = iAllocateW16Handle(pLocalDC, ihBrush, REALIZED_BRUSH);
  1001. if (ihW16 == -1)
  1002. goto error_exit ;
  1003. // Create the w32 brush and store it in the w16 slot table.
  1004. // We assume that the bitmap info is followed by the bits immediately,
  1005. // i.e. it is a packed dib.
  1006. // This brush is needed by the helper DC for BitBlt simulations.
  1007. pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle
  1008. = CreateDIBPatternBrushPt((LPVOID) pBitmapInfo, (UINT) iUsage);
  1009. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle != 0,
  1010. "MF3216: CreateDIBPatternBrushPt failed");
  1011. // We need to convert new bitmap info formats to the win3 formats.
  1012. if (pBitmapInfo->bmiHeader.biPlanes != 1
  1013. || pBitmapInfo->bmiHeader.biBitCount == 16
  1014. || pBitmapInfo->bmiHeader.biBitCount == 32)
  1015. {
  1016. if (!(hbm = CreateDIBitmap(pLocalDC->hdcHelper,
  1017. (LPBITMAPINFOHEADER) pBitmapInfo,
  1018. CBM_INIT | CBM_CREATEDIB,
  1019. pBits,
  1020. (LPBITMAPINFO) pBitmapInfo,
  1021. (UINT) iUsage)))
  1022. goto error_exit ;
  1023. bmih = *(PBITMAPINFOHEADER) pBitmapInfo;
  1024. bmih.biPlanes = 1;
  1025. bmih.biBitCount = 24;
  1026. bmih.biCompression = BI_RGB;
  1027. bmih.biSizeImage = 0;
  1028. bmih.biClrUsed = 0;
  1029. bmih.biClrImportant = 0;
  1030. cbBits24 = CJSCAN(bmih.biWidth,bmih.biPlanes,bmih.biBitCount)
  1031. * ABS(bmih.biHeight);
  1032. pBits24 = (LPBYTE) LocalAlloc(LMEM_FIXED, cbBits24);
  1033. if (pBits24 == (LPBYTE) NULL)
  1034. goto error_exit;
  1035. // Get bitmap info and bits in 24bpp.
  1036. if (!GetDIBits(pLocalDC->hdcHelper,
  1037. hbm,
  1038. 0,
  1039. (UINT) bmih.biHeight,
  1040. pBits24,
  1041. (LPBITMAPINFO) &bmih,
  1042. DIB_RGB_COLORS))
  1043. goto error_exit;
  1044. b = bEmitWin16CreateDIBPatternBrush(pLocalDC,
  1045. (PBITMAPINFO) &bmih,
  1046. sizeof(bmih),
  1047. pBits24,
  1048. cbBits24,
  1049. (WORD) DIB_RGB_COLORS,
  1050. (WORD) BS_DIBPATTERN
  1051. ) ;
  1052. }
  1053. else
  1054. {
  1055. // Call the Win16 routine to emit the brush to the metafile.
  1056. b = bEmitWin16CreateDIBPatternBrush(pLocalDC,
  1057. pBitmapInfo,
  1058. cbBitmapInfo,
  1059. pBits,
  1060. cbBits,
  1061. (WORD) iUsage,
  1062. (WORD) BS_DIBPATTERN
  1063. ) ;
  1064. }
  1065. error_exit:
  1066. if (hbm)
  1067. DeleteObject(hbm);
  1068. if (pBits24)
  1069. LocalFree((HANDLE) pBits24);
  1070. return(b) ;
  1071. }
  1072. /***************************************************************************
  1073. * CreatePen - Win32 to Win16 Metafile Converter Entry Point
  1074. **************************************************************************/
  1075. BOOL WINAPI DoCreatePen
  1076. (
  1077. PLOCALDC pLocalDC,
  1078. INT ihPen,
  1079. PLOGPEN pLogPen
  1080. )
  1081. {
  1082. EXTLOGPEN ExtLogPen ;
  1083. BOOL b ;
  1084. ExtLogPen.elpPenStyle = PS_GEOMETRIC | pLogPen->lopnStyle ;
  1085. ExtLogPen.elpWidth = (UINT) pLogPen->lopnWidth.x ;
  1086. ExtLogPen.elpBrushStyle = BS_SOLID ;
  1087. ExtLogPen.elpColor = pLogPen->lopnColor ;
  1088. ExtLogPen.elpNumEntries = 0 ;
  1089. // ExtLogPen.elpHatch = 0 ;
  1090. // ExtLogPen.elpStyleEntry[0] = 0;
  1091. b = DoExtCreatePen(pLocalDC, ihPen, &ExtLogPen) ;
  1092. return (b) ;
  1093. }
  1094. /***************************************************************************
  1095. * ExtCreatePen - Win32 to Win16 Metafile Converter Entry Point
  1096. **************************************************************************/
  1097. BOOL WINAPI DoExtCreatePen
  1098. (
  1099. PLOCALDC pLocalDC,
  1100. INT ihPen,
  1101. PEXTLOGPEN pExtLogPen
  1102. )
  1103. {
  1104. BOOL b ;
  1105. WORD iStyle ;
  1106. POINTS ptsWidth ;
  1107. INT ihW16 ;
  1108. UINT iPenStyle ;
  1109. POINTL ptlWidth ;
  1110. COLORREF crColor ;
  1111. b = FALSE;
  1112. // Get pen style.
  1113. iPenStyle = pExtLogPen->elpPenStyle & PS_STYLE_MASK ;
  1114. switch(iPenStyle)
  1115. {
  1116. case PS_SOLID:
  1117. case PS_DASH:
  1118. case PS_DOT:
  1119. case PS_DASHDOT:
  1120. case PS_DASHDOTDOT:
  1121. case PS_NULL:
  1122. case PS_INSIDEFRAME:
  1123. break ;
  1124. case PS_ALTERNATE:
  1125. iPenStyle = PS_DOT ;
  1126. break ;
  1127. case PS_USERSTYLE:
  1128. default:
  1129. // CR1: default to solid.
  1130. iPenStyle = PS_SOLID ;
  1131. break ;
  1132. }
  1133. // Get pen color.
  1134. switch (pExtLogPen->elpBrushStyle)
  1135. {
  1136. case BS_SOLID:
  1137. case BS_HATCHED:
  1138. crColor = pExtLogPen->elpColor ;
  1139. break;
  1140. // If the extended pen contains a hollow brush, then
  1141. // we will emit a NULL pen.
  1142. case BS_NULL: // BS_HOLLOW is the same as BS_NULL
  1143. iPenStyle = PS_NULL ;
  1144. crColor = 0 ;
  1145. break;
  1146. // Win3.x does not support pens with bitmap patterns.
  1147. // So we will just use solid pens here. Since we do not
  1148. // know what pen color to use, we choose the text color.
  1149. case BS_PATTERN:
  1150. case BS_DIBPATTERN:
  1151. case BS_DIBPATTERNPT:
  1152. default:
  1153. crColor = pLocalDC->crTextColor ;
  1154. break;
  1155. }
  1156. // Get pen width.
  1157. // If this is a cosmetic pen then the width is 0.
  1158. ptlWidth.y = 0 ;
  1159. if ((pExtLogPen->elpPenStyle & PS_TYPE_MASK) == PS_COSMETIC)
  1160. ptlWidth.x = 0 ;
  1161. else
  1162. ptlWidth.x = pExtLogPen->elpWidth ;
  1163. // Allocate the W16 handle.
  1164. ihW16 = iAllocateW16Handle(pLocalDC, ihPen, REALIZED_PEN);
  1165. if (ihW16 == -1)
  1166. goto error_exit ;
  1167. // This is where we need to create a pen for helper DC.
  1168. // We do not select it into the helper DC at this time.
  1169. pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle
  1170. = CreatePen((int) iPenStyle, ptlWidth.x, crColor) ;
  1171. ASSERTGDI(pLocalDC->pW16ObjHndlSlotStatus[ihW16].w32Handle != 0,
  1172. "MF3216: DoExtCreatePen, CreatePen failed");
  1173. // Get pen width in play time page units.
  1174. ptlWidth.x = (LONG) iMagnitudeXform(pLocalDC, (INT) ptlWidth.x, CX_MAG);
  1175. // Set the Win16 pen attributes
  1176. iStyle = (WORD) iPenStyle ;
  1177. ptsWidth.x = (WORD) ptlWidth.x ;
  1178. ptsWidth.y = (WORD) ptlWidth.y ;
  1179. // Call the Win16 routine to emit the pen to the metafile.
  1180. b = bEmitWin16CreatePen(pLocalDC, iStyle, &ptsWidth, crColor) ;
  1181. error_exit:
  1182. return(b) ;
  1183. }
  1184. /***************************************************************************
  1185. * DoRemoveObjects - Remove the objects that were created in the first
  1186. * XOR pass
  1187. **************************************************************************/
  1188. BOOL WINAPI DoRemoveObjects(
  1189. PLOCALDC pLocalDC
  1190. )
  1191. {
  1192. BOOL b = TRUE ;
  1193. UINT i;
  1194. INT iNorm ;
  1195. INT ihW32Norm ;
  1196. ASSERTGDI( pLocalDC->iXORPass == OBJECTRECREATION,
  1197. "DoRemoveObject used with the wrong XOR Pass" ) ;
  1198. // GillesK
  1199. // We have to go through the list of 16-bit handles and delete
  1200. // every single object that was created during this pass. This
  1201. // is necessary to make sure that we have the exact same state
  1202. // of objects when we restart the second pass so that no object
  1203. // creation will fail and give wrong results.
  1204. // Don't touch the stock objects
  1205. for( i = STOCK_LAST + 1 ; i < pLocalDC->cW32ToW16ObjectMap ; i++ )
  1206. {
  1207. iNorm = pLocalDC->piW32ToW16ObjectMap[i] ;
  1208. if( iNorm != UNMAPPED && pLocalDC->pW16ObjHndlSlotStatus[iNorm].iXORPassCreation == DRAWXORPASS )
  1209. {
  1210. // If there was a Win32 handle associated with this Win16 handle
  1211. // then the w32Handle field of the W16ObjHndlSlotStatus[ihW16]
  1212. // entry in the handle slot status array will be non-null. If
  1213. // it is non-null then we should delete the Win32 handle at this time.
  1214. b = DoDeleteObject( pLocalDC, i- ( STOCK_LAST + 1 ) ) ;
  1215. if( !b )
  1216. break ;
  1217. }
  1218. }
  1219. return b ;
  1220. }
  1221. /***************************************************************************
  1222. * DoDeleteRecreationSlots - Remove the recreation object slots because
  1223. * they will not be used.
  1224. **************************************************************************/
  1225. BOOL WINAPI DoDeleteRecreationSlots(
  1226. PLOCALDC pLocalDC
  1227. )
  1228. {
  1229. BOOL b = TRUE ;
  1230. while(pLocalDC->pW16RecreationSlot != NULL)
  1231. {
  1232. PW16RECREATIONSLOT l_pSlot = pLocalDC->pW16RecreationSlot ;
  1233. pLocalDC->pW16RecreationSlot = pLocalDC->pW16RecreationSlot->pNext ;
  1234. LocalFree(l_pSlot) ;
  1235. }
  1236. return b ;
  1237. }