home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / Sources / FWPictur.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  20.6 KB  |  767 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWPictur.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWPICTUR_H
  13. #include "FWPictur.h"
  14. #endif
  15.  
  16. #ifndef FWGRGLOB_H
  17. #include "FWGrGlob.h"
  18. #endif
  19.  
  20. #ifndef FWGRUTIL_H
  21. #include "FWGrUtil.h"
  22. #endif
  23.  
  24. #ifndef FWGDEV_H
  25. #include "FWGDev.h"
  26. #endif
  27.  
  28. #ifndef FWGC_H
  29. #include "FWGC.h"
  30. #endif
  31.  
  32. #ifndef FWODGEOM_H
  33. #include "FWODGeom.h"
  34. #endif
  35.  
  36. // ----- OS Includes -----
  37.  
  38. #ifndef FWRESACC_H
  39. #include "FWResAcc.h"
  40. #endif
  41.  
  42. #ifndef FWRESSIN_H
  43. #include "FWResSin.h"
  44. #endif
  45.  
  46. #ifndef FWACQUIR_H
  47. #include "FWAcquir.h"
  48. #endif
  49.  
  50. // ----- Foundation Includes -----
  51.  
  52. #ifndef FWSTREAM_H
  53. #include "FWStream.h"
  54. #endif
  55.  
  56. #ifndef FWDEBUG_H
  57. #include "FWDebug.h"
  58. #endif
  59.  
  60. #ifndef FWSTRMRW_H
  61. #include "FWStrmRW.h"
  62. #endif
  63.  
  64. #ifndef FWMEMMGR_H
  65. #include "FWMemMgr.h"
  66. #endif
  67.  
  68. // ----- OpenDoc Includes -----
  69.  
  70. #ifndef SOM_ODCanvas_xh
  71. #include <Canvas.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODShape_xh
  75. #include <Shape.xh>
  76. #endif
  77.  
  78. #ifndef SOM_ODTransform_xh
  79. #include <Trnsform.xh>
  80. #endif
  81.  
  82. // ----- Macintosh Includes -----
  83.  
  84. #if defined(FW_BUILD_MAC) && !defined(__RESOURCES__)
  85. #include <Resources.h>
  86. #endif
  87.  
  88. //========================================================================================
  89. //    RunTime Info
  90. //========================================================================================
  91.  
  92. #if FW_LIB_EXPORT_PRAGMAS
  93. #pragma lib_export on
  94. #endif
  95.  
  96. #ifdef FW_BUILD_MAC
  97. #pragma segment FWGraphics_Picture
  98. #endif
  99.  
  100. FW_DEFINE_CLASS_M1(FW_PPicture, FW_CGraphicCountedPtr)
  101. FW_DEFINE_CLASS_M1(FW_CPictureRep, FW_CGraphicCountedPtrRep)
  102.  
  103. FW_REGISTER_ARCHIVABLE_CLASS(FW_LPictureRep, FW_CPictureRep, FW_CPictureRep::Read, FW_CGraphicCountedPtrRep::Write)
  104.  
  105. //========================================================================================
  106. //    class FW_PPicture
  107. //========================================================================================
  108.  
  109. //----------------------------------------------------------------------------------------
  110. //    FW_PPicture::FW_PPicture
  111. //----------------------------------------------------------------------------------------
  112.  
  113. FW_PPicture::FW_PPicture() :
  114.     FW_CGraphicCountedPtr()
  115. {
  116.     FW_END_CONSTRUCTOR
  117. }
  118.  
  119. //----------------------------------------------------------------------------------------
  120. //    FW_PPicture::FW_PPicture
  121. //----------------------------------------------------------------------------------------
  122.  
  123. FW_PPicture::FW_PPicture(FW_PlatformPict platformPict) :
  124.     FW_CGraphicCountedPtr()
  125. {
  126.     SetRep(new FW_CPictureRep(platformPict));
  127.     
  128.     FW_END_CONSTRUCTOR
  129. }
  130.  
  131. //----------------------------------------------------------------------------------------
  132. //    FW_PPicture::FW_PPicture
  133. //----------------------------------------------------------------------------------------
  134.  
  135. FW_PPicture::FW_PPicture(FW_CResourceFile& resourceFile, FW_ResourceId resourceId) :
  136.     FW_CGraphicCountedPtr()
  137. {
  138.     SetRep(new FW_CPictureRep(resourceFile, resourceId));
  139.     
  140.     FW_END_CONSTRUCTOR
  141. }
  142.  
  143. //----------------------------------------------------------------------------------------
  144. //    FW_PPicture::FW_PPicture
  145. //----------------------------------------------------------------------------------------
  146.  
  147. FW_PPicture::FW_PPicture(const FW_PPicture& other) :
  148.     FW_CGraphicCountedPtr(other)
  149. {
  150.     FW_END_CONSTRUCTOR
  151. }
  152.  
  153. //----------------------------------------------------------------------------------------
  154. //    FW_PPicture::~FW_PPicture
  155. //----------------------------------------------------------------------------------------
  156.  
  157. FW_PPicture::~FW_PPicture()
  158. {
  159.     FW_START_DESTRUCTOR
  160. }
  161.  
  162. //----------------------------------------------------------------------------------------
  163. //    FW_PPicture::operator=
  164. //----------------------------------------------------------------------------------------
  165.  
  166. FW_PPicture& FW_PPicture::operator=(const FW_PPicture& other)
  167. {
  168.     // We don't need to test this == &other because SetRep will do it
  169.     SetRep(other.GetRep());
  170.     return *this;
  171. }
  172.  
  173. //========================================================================================
  174. //    CLASS FW_CPictureRep
  175. //========================================================================================
  176.  
  177. //----------------------------------------------------------------------------------------
  178. //    Placeable (Aldus) metafile definitions for Windows
  179. //----------------------------------------------------------------------------------------
  180.  
  181. #ifdef FW_BUILD_WIN
  182.  
  183. #pragma pack(push,1)
  184.  
  185. struct RECT16
  186. {
  187.     short   left;
  188.     short   top;
  189.     short   right;
  190.     short   bottom;
  191. };
  192.  
  193. struct SAldusHeader
  194. {
  195.     DWORD   key;
  196.     WORD    hmf;
  197.     RECT16    bbox;
  198.     WORD    inch;
  199.     DWORD   reserved;
  200.     WORD    checksum;
  201. } ;
  202.  
  203. #pragma pack(pop)
  204.  
  205. const DWORD kAldusKey =    0x9AC6CDD7l;
  206.  
  207. #endif
  208.  
  209. //----------------------------------------------------------------------------------------
  210. //    FW_CPictureRep::FW_CPictureRep
  211. //----------------------------------------------------------------------------------------
  212.  
  213. FW_CPictureRep::FW_CPictureRep():
  214. #ifdef FW_BUILD_MAC
  215.     fMacLockCount(0),
  216. #endif
  217.     FW_CGraphicCountedPtrRep(),
  218.     fPlatformPict(NULL),
  219.     fOwnPicture(FALSE)
  220. {
  221. }
  222.  
  223. //----------------------------------------------------------------------------------------
  224. //    FW_CPictureRep::FW_CPictureRep
  225. //----------------------------------------------------------------------------------------
  226.  
  227. FW_CPictureRep::FW_CPictureRep(FW_CReadableStream& archive):
  228. #ifdef FW_BUILD_MAC
  229.     fMacLockCount(0),
  230. #endif
  231.     FW_CGraphicCountedPtrRep(),
  232.     fPlatformPict(NULL),
  233.     fOwnPicture(FALSE)
  234. {
  235.     ReadFrom(archive);
  236. }
  237.  
  238. //----------------------------------------------------------------------------------------
  239. //    FW_CPictureRep::FW_CPictureRep
  240. //----------------------------------------------------------------------------------------
  241.  
  242. FW_CPictureRep::FW_CPictureRep(FW_PlatformPict platformPict) :
  243. #ifdef FW_BUILD_MAC
  244.     fMacLockCount(0),
  245. #endif
  246.     FW_CGraphicCountedPtrRep(),
  247.     fPlatformPict(platformPict),
  248.     fOwnPicture(FALSE)
  249. {
  250. }
  251.  
  252. //----------------------------------------------------------------------------------------
  253. //    FW_CPictureRep::FW_CPictureRep
  254. //----------------------------------------------------------------------------------------
  255.  
  256. FW_CPictureRep::FW_CPictureRep(FW_CResourceFile& resourceFile, FW_ResourceId resourceId) :
  257. #ifdef FW_BUILD_MAC
  258.     fMacLockCount(0),
  259. #endif
  260.     FW_CGraphicCountedPtrRep(),
  261.     fPlatformPict(NULL),
  262.     fOwnPicture(FALSE)
  263. {
  264.     LoadPictureFromResource(resourceFile, resourceId);
  265. }
  266.  
  267. //----------------------------------------------------------------------------------------
  268. //    FW_CPictureRep::~FW_CPictureRep
  269. //----------------------------------------------------------------------------------------
  270.  
  271. FW_CPictureRep::~FW_CPictureRep()
  272. {
  273.     DisposePlatformPict();
  274. }
  275.  
  276. //----------------------------------------------------------------------------------------
  277. //    FW_CPictureRep::DisposePlatformPict
  278. //----------------------------------------------------------------------------------------
  279.  
  280. void FW_CPictureRep::DisposePlatformPict()
  281. {
  282.     if (fOwnPicture && fPlatformPict != NULL)
  283.     {
  284. #ifdef FW_BUILD_MAC
  285.         ::KillPicture(fPlatformPict);
  286. #endif
  287. #ifdef FW_BUILD_WIN
  288.         ::DeleteEnhMetaFile(fPlatformPict);
  289. #endif
  290.     }
  291.     
  292.     fPlatformPict = NULL;
  293. }
  294.  
  295. //----------------------------------------------------------------------------------------
  296. //    FW_CPictureRep::Copy
  297. //----------------------------------------------------------------------------------------
  298.  
  299. FW_PPicture FW_CPictureRep::Copy() const
  300. {
  301.     FW_ASSERT(fPlatformPict != NULL);
  302.  
  303.     FW_PlatformPict newHandle;
  304.  
  305. #ifdef FW_BUILD_MAC
  306.     newHandle = (FW_PlatformPict) FW_CMemoryManager::CopySystemHandle((FW_PlatformHandle)fPlatformPict);
  307. #endif
  308. #ifdef FW_BUILD_WIN
  309.     newHandle = ::CopyEnhMetaFile(fPlatformPict, NULL);
  310. #endif
  311.  
  312.     return FW_PPicture(newHandle);
  313. }
  314.  
  315. //----------------------------------------------------------------------------------------
  316. //    FW_CPictureRep::OrphanPlatformPict
  317. //----------------------------------------------------------------------------------------
  318.  
  319. FW_PlatformPict FW_CPictureRep::OrphanPlatformPict()
  320. {
  321.     FW_ASSERT(fOwnPicture == TRUE);    // Test first that we are the owner
  322.     fOwnPicture = FALSE;
  323.     return fPlatformPict;
  324. }
  325.  
  326. //----------------------------------------------------------------------------------------
  327. //    FW_CPictureRep::SetPlatformPict
  328. //----------------------------------------------------------------------------------------
  329.  
  330. void FW_CPictureRep::SetPlatformPict(FW_PlatformPict newPict)
  331. {
  332.     if (fPlatformPict != newPict)
  333.     {
  334.         DisposePlatformPict();
  335.         fPlatformPict = newPict;
  336.     }
  337.     
  338.     fOwnPicture = FALSE;
  339. }
  340.  
  341. //----------------------------------------------------------------------------------------
  342. //    FW_CPictureRep::AdoptPlatformPict
  343. //----------------------------------------------------------------------------------------
  344.  
  345. void FW_CPictureRep::AdoptPlatformPict(FW_PlatformPict newPict)
  346. {    
  347.     SetPlatformPict(newPict);
  348.     fOwnPicture = TRUE;
  349. }
  350.  
  351. //----------------------------------------------------------------------------------------
  352. //    FW_CPictureRep::LoadPictureFromResource
  353. //----------------------------------------------------------------------------------------
  354.  
  355. void FW_CPictureRep::LoadPictureFromResource(FW_CResourceFile& resourceFile,
  356.                                               FW_ResourceId resourceId)
  357. {    
  358. #ifdef FW_BUILD_MAC
  359.     FW_PlatformPict newPict = 
  360.         (FW_PlatformPict) resourceFile.PrivGetSpecialResource(resourceId, FW_kPicture);
  361.     // Because of CFM we have to detach the resource
  362.     ::DetachResource((Handle)newPict);
  363.     AdoptPlatformPict(newPict);
  364. #endif
  365.  
  366. #ifdef FW_BUILD_WIN
  367.     FW_CResource resource(resourceFile, resourceId, FW_kPicture);
  368.     FW_CResourceSink sink(resource);
  369.     FW_CReadableStream stream(&sink);
  370.     ReadFrom(stream);
  371. #endif
  372. }
  373.  
  374. //----------------------------------------------------------------------------------------
  375. //    FW_CPictureRep::Flatten
  376. //----------------------------------------------------------------------------------------
  377.  
  378. void FW_CPictureRep::Flatten(FW_CWritableStream& archive) const
  379. {
  380.     WriteTo(archive);
  381. }
  382.  
  383. //----------------------------------------------------------------------------------------
  384. //    FW_CPictureRep::WriteTo
  385. //----------------------------------------------------------------------------------------
  386.  
  387. void FW_CPictureRep::WriteTo(const FW_CWritableStream& stream) const
  388. {
  389. #ifdef FW_BUILD_MAC
  390.     unsigned long picSize = FW_CMemoryManager::GetSystemHandleSize((FW_PlatformHandle)fPlatformPict);
  391.     stream << picSize;
  392.     FW_CPictureRep* self = (FW_CPictureRep*)this;
  393.     
  394.     self->MacLock();
  395.     
  396.     FW_TRY
  397.     {
  398.         stream.Write(*fPlatformPict, picSize);
  399.     }
  400.     FW_CATCH_BEGIN
  401.     FW_CATCH_EVERYTHING()
  402.     {
  403.         self->MacUnlock();
  404.         FW_THROW_SAME();
  405.     }
  406.     FW_CATCH_END
  407.  
  408.     self->MacUnlock();    
  409. #endif    
  410.  
  411. #ifdef FW_BUILD_WIN
  412.     UINT bitsSize = ::GetEnhMetaFileBits(fPlatformPict, 0, NULL);
  413.     
  414.     BYTE* bitsBuf = new BYTE[bitsSize];
  415.     ::GetEnhMetaFileBits(fPlatformPict, bitsSize, bitsBuf);
  416.     
  417.     stream.Write(bitsBuf, bitsSize);
  418.  
  419.     delete[] bitsBuf;
  420. #endif
  421. }
  422.  
  423. //----------------------------------------------------------------------------------------
  424. //    FW_CPictureRep::ReadFrom
  425. //----------------------------------------------------------------------------------------
  426.  
  427. void FW_CPictureRep::ReadFrom(const FW_CReadableStream& stream)
  428. {
  429. #ifdef FW_BUILD_MAC
  430.     unsigned long picSize;
  431.     stream >> picSize;
  432.     
  433.     fPlatformPict = (FW_PlatformPict) FW_CMemoryManager::AllocateSystemHandle(picSize);
  434.             
  435.     MacLock();
  436.     
  437.     FW_TRY
  438.     {
  439.         stream.Read(*fPlatformPict, picSize);
  440.     }
  441.     FW_CATCH_BEGIN
  442.     FW_CATCH_EVERYTHING()
  443.     {
  444.         MacUnlock();
  445.         ::DisposeHandle((Handle)fPlatformPict);
  446.         fPlatformPict = NULL;
  447.         FW_THROW_SAME();
  448.     }
  449.     FW_CATCH_END
  450.  
  451.     MacUnlock();
  452. #endif
  453. #ifdef FW_BUILD_WIN
  454.     HENHMETAFILE metafile = NULL;
  455.  
  456.     // Check if there is an Aldus metafile header
  457.     SAldusHeader aldusHeader;
  458.     stream.Read(&aldusHeader, sizeof(aldusHeader));
  459.     if(aldusHeader.key == kAldusKey)
  460.     {
  461.         // ----- This is an Aldus format metafile
  462.  
  463.         // Read the header
  464.         METAHEADER mfHeader;
  465.         stream.Read(&mfHeader, sizeof(mfHeader));
  466.  
  467.         // Read the bits
  468.         size_t bitsSize = mfHeader.mtSize * 2L;
  469.         BYTE* bitsBuf = new BYTE[bitsSize];
  470.         FW_CMemoryManager::CopyMemory(&mfHeader, bitsBuf, sizeof(mfHeader));
  471.         stream.Read(bitsBuf + sizeof(mfHeader), bitsSize - sizeof(mfHeader));
  472.  
  473.         // Convert an Aldus (Win16) metafile to a Win32 Enhanced Metafile
  474.         METAFILEPICT mfPict;
  475.         mfPict.mm = MM_ANISOTROPIC;
  476.         mfPict.xExt = (aldusHeader.bbox.right - aldusHeader.bbox.left) * 2540 / aldusHeader.inch;
  477.         mfPict.yExt = (aldusHeader.bbox.bottom - aldusHeader.bbox.top) * 2540 / aldusHeader.inch;
  478.  
  479.         metafile = ::SetWinMetaFileBits(bitsSize, bitsBuf, NULL, &mfPict);
  480.         delete[] bitsBuf;
  481.     }
  482.     else
  483.     {
  484.         // ----- Not an Aldus metafile, try Win32 Enhanced metafile
  485.  
  486.         // Read the header
  487.         ENHMETAHEADER enhHeader;
  488.         FW_CMemoryManager::CopyMemory(&aldusHeader, &enhHeader, sizeof(aldusHeader));
  489.         stream.Read((char*) &enhHeader + sizeof(aldusHeader), sizeof(enhHeader) - sizeof(aldusHeader));
  490.  
  491.         // Verify the header
  492.         if(enhHeader.iType == EMR_HEADER || enhHeader.nSize == sizeof(enhHeader))
  493.         {
  494.             // Read the bits
  495.             size_t bitsSize = enhHeader.nBytes;
  496.             BYTE* bitsBuf = new BYTE[bitsSize];
  497.             FW_CMemoryManager::CopyMemory(&enhHeader, bitsBuf, sizeof(enhHeader));
  498.             stream.Read(bitsBuf + sizeof(enhHeader), bitsSize - sizeof(enhHeader));
  499.     
  500.             // Create a metafile and set the bits
  501.              metafile = ::SetEnhMetaFileBits(bitsSize, bitsBuf);
  502.             delete[] bitsBuf;
  503.         }
  504.     }
  505.  
  506.     if(metafile == NULL)
  507.         FW_Failure(FW_xInvalidPictureData);
  508.  
  509.     // Save metafile info
  510.     AdoptPlatformPict(metafile);
  511. #endif
  512. }
  513.  
  514. //----------------------------------------------------------------------------------------
  515. //    FW_CPictureRep::IsEqual
  516. //----------------------------------------------------------------------------------------
  517.  
  518. FW_Boolean FW_CPictureRep::IsEqual(const FW_CGraphicCountedPtrRep* other) const
  519. {
  520.     if (other == this)
  521.         return TRUE;
  522.         
  523. #ifdef FW_DEBUG
  524.     FW_CPictureRep* pictureRep = FW_DYNAMIC_CAST(FW_CPictureRep, other);
  525.     FW_ASSERT(pictureRep != NULL);
  526. #else
  527.     FW_CPictureRep* pictureRep = (FW_CPictureRep*)other;
  528. #endif
  529.  
  530.     return fPlatformPict == pictureRep->fPlatformPict;
  531. }
  532.  
  533. #ifdef FW_BUILD_MAC
  534. //----------------------------------------------------------------------------------------
  535. //    FW_CPictureRep::MacLock
  536. //----------------------------------------------------------------------------------------
  537.  
  538. void FW_CPictureRep::MacLock()
  539. {
  540.     FW_ASSERT(fPlatformPict != NULL);
  541.  
  542.     if (fMacLockCount == 0)
  543.         FW_CMemoryManager::LockSystemHandle((FW_PlatformHandle)fPlatformPict);
  544.     
  545.     fMacLockCount++;
  546. }
  547. #endif
  548.  
  549. #ifdef FW_BUILD_MAC
  550. //----------------------------------------------------------------------------------------
  551. //    FW_CPictureRep::MacUnlock
  552. //----------------------------------------------------------------------------------------
  553.  
  554. void FW_CPictureRep::MacUnlock()
  555. {
  556.     FW_ASSERT(fPlatformPict != NULL);
  557.     FW_ASSERT(fMacLockCount != 0);
  558.     
  559.     FW_CMemoryManager::UnlockSystemHandle((FW_PlatformHandle)fPlatformPict);    
  560.     fMacLockCount--;
  561. }
  562. #endif
  563.  
  564. //----------------------------------------------------------------------------------------
  565. //    FW_CPictureRep::GetPictBounds
  566. //----------------------------------------------------------------------------------------
  567.  
  568. void FW_CPictureRep::GetPictBounds(FW_CRect& bounds) const
  569. {
  570. #ifdef FW_BUILD_MAC
  571.     bounds.SetInt(
  572.         0,
  573.         0,
  574.         (*fPlatformPict)->picFrame.right - (*fPlatformPict)->picFrame.left,
  575.         (*fPlatformPict)->picFrame.bottom - (*fPlatformPict)->picFrame.top
  576.     );
  577. #endif
  578.  
  579. #ifdef FW_BUILD_WIN
  580.     ENHMETAHEADER emh;
  581.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  582.     
  583.     // emh.rclBounds is the bounding rectangle in pixels, computed by GDI
  584.  
  585.     bounds.SetInt(
  586.         emh.rclBounds.left,
  587.         emh.rclBounds.top,
  588.         emh.rclBounds.right,
  589.         emh.rclBounds.bottom
  590.     );
  591. #endif
  592. }
  593.  
  594. //----------------------------------------------------------------------------------------
  595. //    FW_CPictureRep::GetPictBounds
  596. //----------------------------------------------------------------------------------------
  597.  
  598. void FW_CPictureRep::GetPictBounds(FW_CGraphicContext& gc, FW_CRect& bounds) const
  599. {
  600. #ifdef FW_BUILD_MAC
  601.     FW_CPoint size = gc.DeviceToLogical(
  602.         (*fPlatformPict)->picFrame.right - (*fPlatformPict)->picFrame.left,
  603.         (*fPlatformPict)->picFrame.bottom - (*fPlatformPict)->picFrame.top
  604.     );
  605.     bounds.Set(FW_IntToFixed(0), FW_IntToFixed(0), size.x, size.y);
  606. #endif
  607.  
  608. #ifdef FW_BUILD_WIN
  609.     ENHMETAHEADER emh;
  610.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  611.  
  612.     // emh.rclFrame is the bounding rectangle as specified by the creator, in 0.01 mm units
  613.  
  614.     FW_CGraphicDevice* device = gc.GetGraphicDevice();
  615.     HDC hDC = *device;
  616.     
  617.     int xRes = ::GetDeviceCaps(hDC, LOGPIXELSX);
  618.     int yRes = ::GetDeviceCaps(hDC, LOGPIXELSY);
  619.  
  620.     FW_SPlatformRect plfmBounds;
  621.  
  622.     plfmBounds.left        = emh.rclFrame.left        * xRes / 2540;
  623.     plfmBounds.top        = emh.rclFrame.top        * yRes / 2540;
  624.     plfmBounds.right    = emh.rclFrame.right    * xRes / 2540;
  625.     plfmBounds.bottom    = emh.rclFrame.bottom    * yRes / 2540;
  626.  
  627.     bounds = gc.DeviceToLogical(plfmBounds);
  628. #endif
  629. }
  630.  
  631. //----------------------------------------------------------------------------------------
  632. //    FW_CPictureRep::Read
  633. //----------------------------------------------------------------------------------------
  634.  
  635. void* FW_CPictureRep::Read(FW_CReadableStream& archive)
  636. {
  637.     return new FW_CPictureRep(archive);
  638. }
  639.  
  640. //----------------------------------------------------------------------------------------
  641. //    FW_CPictureRep::GetPlatformPict
  642. //----------------------------------------------------------------------------------------
  643.  
  644. FW_PlatformPict FW_CPictureRep::GetPlatformPict() const
  645. {
  646.     return fPlatformPict;
  647. }
  648.  
  649. //========================================================================================
  650. //    class FW_CPictureContext
  651. //========================================================================================
  652.  
  653. //----------------------------------------------------------------------------------------
  654. //    FW_CPictureContext::FW_CPictureContext
  655. //----------------------------------------------------------------------------------------
  656.  
  657. FW_CPictureContext::FW_CPictureContext(Environment* ev,
  658.                                        FW_PPicture& picture,
  659.                                        FW_CFixed xSize,
  660.                                        FW_CFixed ySize) :
  661.     FW_CGraphicContext(ev),
  662. #ifdef FW_BUILD_MAC
  663.     fMacPictHandle(NULL),
  664. #endif
  665.     fPicture(picture),
  666.     fGraphicDevice(NULL)
  667. {
  668.     ODPlatformCanvas platformCanvas;
  669.  
  670.     FW_CRect clipRect;
  671.     
  672. #ifdef FW_BUILD_MAC
  673.     platformCanvas = FW_gScratchWindow;
  674.     clipRect.Set(FW_IntToFixed(0), FW_IntToFixed(0), xSize, ySize);
  675. #endif
  676.  
  677. #ifdef FW_BUILD_WIN
  678.     HDC hDCRef = ::GetDC(NULL);
  679.     
  680.     int xRes = ::GetDeviceCaps(hDCRef, LOGPIXELSX);
  681.     int yRes = ::GetDeviceCaps(hDCRef, LOGPIXELSY);
  682.     
  683.     int xDevMM = ::GetDeviceCaps(hDCRef, HORZSIZE);
  684.     int yDevMM = ::GetDeviceCaps(hDCRef, VERTSIZE);
  685.     int xDevPix = ::GetDeviceCaps(hDCRef, HORZRES);
  686.     int yDevPix = ::GetDeviceCaps(hDCRef, VERTRES);
  687.  
  688.     // The size comes in at 72dpi: convert to HiMetric units (0.01 mm)
  689.     FW_SPlatformRect boundsMM(0, 0, xSize.AsInt() * 2540 / 72, ySize.AsInt() * 2540 / 72);
  690.  
  691.     platformCanvas = ::CreateEnhMetaFile(hDCRef, NULL, &boundsMM, NULL);
  692.  
  693.     // Convert size to pixels, for use in the coordinate system
  694.     FW_CFixed fx72 = FW_IntToFixed(72);
  695.     
  696.     int xSizePix = 
  697.         (FW_WideMultiply(xSize, FW_IntToFixed(xRes)) / fx72).AsInt();
  698.         //  FixedToInt(::FW_FixMul(xSize, ::FW_FixDiv(IntToFixed(xRes), IntToFixed(72))));
  699.  
  700.     int ySizePix =
  701.         (FW_WideMultiply(ySize, FW_IntToFixed(yRes)) / fx72).AsInt();
  702.         // FixedToInt(::FW_FixMul(ySize, ::FW_FixDiv(IntToFixed(yRes), IntToFixed(72))));
  703.  
  704.     int xDraw = (254 * xSizePix * xDevPix) / (100 * xDevMM);
  705.     int yDraw = (254 * ySizePix * yDevPix) / (100 * yDevMM);
  706.  
  707.     clipRect.SetInt(0, 0, xDraw, yDraw);
  708.  
  709.     ::ReleaseDC(NULL, hDCRef);
  710. #endif
  711.  
  712.     fGraphicDevice = new FW_CGraphicDevice(ev, platformCanvas);
  713.  
  714. #ifdef FW_BUILD_WIN
  715.     // Set the resolution: (xSize, ySize) should map to (xDraw, yDraw)
  716.     FW_CPoint deviceResoltion(
  717.         xSize / FW_IntToFixed(xDraw),
  718.         ySize / FW_IntToFixed(yDraw));
  719.     fGraphicDevice->SetResolution(deviceResoltion);
  720. #endif
  721.  
  722.     FW_CAcquiredODShape aqClipShape = ::FW_NewODShape(ev, clipRect);
  723.  
  724.     InitGraphicContext(fGraphicDevice,
  725.                        NULL,
  726.                        aqClipShape);
  727.  
  728. #ifdef FW_BUILD_MAC
  729.     FW_SPlatformRect plfmBounds(0, 0, xSize.AsInt(), ySize.AsInt());
  730.  
  731.     ::PortSize(plfmBounds.right, plfmBounds.bottom);
  732.     fMacPictHandle = ::OpenPicture(&plfmBounds);
  733. #endif
  734.  
  735.     FW_END_CONSTRUCTOR
  736. }
  737.  
  738. //----------------------------------------------------------------------------------------
  739. //    FW_CPictureContext::~FW_CPictureContext
  740. //----------------------------------------------------------------------------------------
  741.  
  742. FW_CPictureContext::~FW_CPictureContext()
  743. {
  744.     FW_START_DESTRUCTOR
  745.  
  746.     FW_PlatformPict newPict;
  747.  
  748. #ifdef FW_BUILD_MAC
  749.     ::ClosePicture();
  750.     newPict = fMacPictHandle;
  751. #endif
  752.  
  753.     // ----- Terminate the superclass
  754.     TerminateGraphicContext();
  755.  
  756. #ifdef FW_BUILD_WIN
  757.     HDC hDC = fGraphicDevice->GetPlatformCanvas();
  758.     newPict = ::CloseEnhMetaFile(hDC);
  759. #endif
  760.  
  761.     // ----- Delete the device
  762.     fGraphicDevice->Release();
  763.  
  764.     // ----- Store the result in the picture
  765.     fPicture = FW_PPicture(newPict);
  766. }
  767.