home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / PRPictur.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  14.5 KB  |  569 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRPictur.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef SLPALETE_H
  13. #include "SLPalete.h"
  14. #endif
  15.  
  16. #ifndef FWODEXCE_H
  17. #include "FWODExce.h"
  18. #endif
  19.  
  20. #ifndef FWBITMAP_H
  21. #include "FWBitmap.h"
  22. #endif
  23.  
  24. #ifndef FWWINRES_H
  25. #include "FWWinRes.h"
  26. #endif
  27.  
  28. #ifndef FWSTRMRW_H
  29. #include "FWStrmRW.h"
  30. #endif
  31.  
  32. #ifndef FWRESOUR_H
  33. #include "FWResour.h"
  34. #endif
  35.  
  36. #ifndef FWGC_H
  37. #include "FWGC.h"
  38. #endif
  39.  
  40. #ifndef PRGDEV_H
  41. #include "PRGDev.h"
  42. #endif
  43.  
  44. #ifndef FWSOMENV_H
  45. #include "FWSOMEnv.h"
  46. #endif
  47.  
  48. #ifndef PRPICTUR_H
  49. #include "PRPictur.h"
  50. #endif
  51.  
  52. #ifndef FWMEMMGR_H
  53. #include "FWMemMgr.h"
  54. #endif
  55.  
  56. #ifndef FWEXCEPT_H
  57. #include "FWExcept.h"
  58. #endif
  59.  
  60. #ifndef SOM_FW_OResourceFile_xh
  61. #include "SLResFil.xh"
  62. #endif
  63.  
  64. // ----- Macintosh Includes -----
  65.  
  66. #if defined(FW_BUILD_MAC) && !defined(__PICTUTILS__)
  67. #include <PictUtils.h>
  68. #endif
  69.  
  70. //========================================================================================
  71. //    RunTime Info
  72. //========================================================================================
  73.  
  74. #ifdef FW_BUILD_MAC
  75. #pragma segment FWGraphics_Picture
  76. #endif
  77.  
  78. FW_DEFINE_AUTO(FW_CPrivPictureRep)
  79.  
  80. //----------------------------------------------------------------------------------------
  81. //    Placeable (Aldus) metafile definitions for Windows
  82. //----------------------------------------------------------------------------------------
  83.  
  84. #ifdef FW_BUILD_WIN
  85.  
  86. #pragma pack(push,1)
  87.  
  88. struct RECT16
  89. {
  90.     short   left;
  91.     short   top;
  92.     short   right;
  93.     short   bottom;
  94. };
  95.  
  96. struct SAldusHeader
  97. {
  98.     DWORD   key;
  99.     WORD    hmf;
  100.     RECT16    bbox;
  101.     WORD    inch;
  102.     DWORD   reserved;
  103.     WORD    checksum;
  104. } ;
  105.  
  106. #pragma pack(pop)
  107.  
  108. const DWORD kAldusKey =    0x9AC6CDD7l;
  109.  
  110. #endif
  111.  
  112. //----------------------------------------------------------------------------------------
  113. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  114. //----------------------------------------------------------------------------------------
  115. //    From Stream: we own the picture
  116.  
  117. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_CReadableStream& stream) :
  118.     fOwnPicture(TRUE),
  119.     fPlatformPict(NULL)
  120. {
  121. #ifdef FW_BUILD_MAC
  122.     fMacLockCount    = 0;
  123. #endif
  124.  
  125.     PrivReadFrom(stream);
  126.     
  127.     FW_END_CONSTRUCTOR
  128. }
  129.  
  130. //----------------------------------------------------------------------------------------
  131. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  132. //----------------------------------------------------------------------------------------
  133. //    From File: we own the picture
  134.  
  135. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_OResourceFile* resourceFile, FW_ResourceID resID) :
  136.     fOwnPicture(TRUE),
  137.     fPlatformPict(NULL)
  138. {
  139.     FW_SOMEnvironment ev;
  140.  
  141. #ifdef FW_BUILD_MAC
  142. FW_UNUSED(resourceFile);
  143.  
  144.     fMacLockCount    = 0;
  145.     FW_ASSERT(::CurResFile() == resourceFile->PrivGetResourceFileID(ev));
  146.     
  147.     FW_PlatformPict newPict = ::GetPicture(resID);
  148.     if (newPict == NULL)
  149.     {
  150.         FW_FailOnError(::ResError());
  151.         FW_Failure(FW_xMemoryExhausted);        
  152.     }
  153.  
  154.     // Because of CFM we have to detach the resource
  155.     ::DetachResource((Handle)newPict);
  156.     AdoptPlatformPict(newPict);
  157. #endif
  158.  
  159. #ifdef FW_BUILD_WIN
  160.     FW_PResource resource(ev, resourceFile, resID, FW_kPicture);
  161.     FW_PResourceSink sink(ev, resource);
  162.     FW_CReadableStream stream(sink);
  163.     PrivReadFrom(stream);
  164. #endif
  165.  
  166.     FW_END_CONSTRUCTOR
  167. }
  168.  
  169. //----------------------------------------------------------------------------------------
  170. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  171. //----------------------------------------------------------------------------------------
  172. //    From platform pict: we own the picture (no copy is made)
  173.  
  174. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_PlatformPict platformPict) :
  175.     fOwnPicture(false),
  176.     fPlatformPict(platformPict)
  177. {
  178.     FW_ASSERT(platformPict != NULL);
  179.     
  180. #ifdef FW_BUILD_MAC
  181.     fMacLockCount    = 0;
  182. #endif
  183.     FW_END_CONSTRUCTOR
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  188. //----------------------------------------------------------------------------------------
  189. //    From another Pict: we own the picture (a copy is made)
  190.  
  191. FW_CPrivPictureRep::FW_CPrivPictureRep(const FW_CPrivPictureRep& other) :
  192.     fOwnPicture(TRUE),
  193.     fPlatformPict(NULL)
  194. {
  195.     FW_PlatformPict otherPict = other.GetPlatformPict();
  196.     
  197. #ifdef FW_BUILD_MAC
  198.     fPlatformPict = (FW_PlatformPict) FW_CMemoryManager::CopySystemHandle((FW_PlatformHandle)otherPict);
  199.     fMacLockCount    = 0;
  200. #endif
  201. #ifdef FW_BUILD_WIN
  202.     fPlatformPict = ::CopyEnhMetaFile(otherPict, NULL);
  203. #endif
  204.     
  205.     if (fPlatformPict == 0)
  206.         FW_Failure(FW_xMemoryExhausted);
  207.  
  208.     FW_END_CONSTRUCTOR
  209. }
  210.  
  211. //----------------------------------------------------------------------------------------
  212. //    FW_CPrivPictureRep::~FW_CPrivPictureRep
  213. //----------------------------------------------------------------------------------------
  214.  
  215. FW_CPrivPictureRep::~FW_CPrivPictureRep()
  216. {
  217.     FW_START_DESTRUCTOR
  218.      PrivDisposePict();
  219. }
  220.  
  221. //----------------------------------------------------------------------------------------
  222. //    FW_CPrivPictureRep::Write
  223. //----------------------------------------------------------------------------------------
  224.  
  225. void FW_CPrivPictureRep::Write(FW_CWritableStream& stream)
  226. {
  227. #ifdef FW_BUILD_MAC
  228.     unsigned long picSize = FW_CMemoryManager::GetSystemHandleSize((FW_PlatformHandle)fPlatformPict);
  229.     stream << picSize;
  230.  
  231.     MacLock();
  232.     
  233.     FW_TRY
  234.     {
  235.         stream.Write(*fPlatformPict, picSize);
  236.     }
  237.     FW_CATCH_BEGIN
  238.     FW_CATCH_EVERYTHING()
  239.     {
  240.         MacUnlock();
  241.         FW_THROW_SAME();
  242.     }
  243.     FW_CATCH_END
  244.  
  245.     MacUnlock();    
  246. #endif    
  247. #ifdef FW_BUILD_WIN
  248.     UINT bitsSize = ::GetEnhMetaFileBits(fPlatformPict, 0, NULL);
  249.  
  250.     BYTE* bitsBuf = new BYTE[bitsSize];
  251.     ::GetEnhMetaFileBits(fPlatformPict, bitsSize, bitsBuf);
  252.     
  253.     FW_TRY
  254.     {
  255.         stream.Write(bitsBuf, bitsSize);
  256.     }
  257.     FW_CATCH_BEGIN
  258.     FW_CATCH_EVERYTHING()
  259.     {
  260.         delete[] bitsBuf;
  261.         FW_THROW_SAME();
  262.     }
  263.     FW_CATCH_END
  264.  
  265.     delete[] bitsBuf;
  266. #endif
  267. }
  268.  
  269. //----------------------------------------------------------------------------------------
  270. //    FW_CPrivPictureRep::IsEqual
  271. //----------------------------------------------------------------------------------------
  272.  
  273. FW_Boolean FW_CPrivPictureRep::IsEqual(const FW_CPrivPictureRep& other) const
  274. {
  275.     return fPlatformPict == other.fPlatformPict;
  276. }
  277.  
  278. //----------------------------------------------------------------------------------------
  279. //    FW_CPrivPictureRep::GetPictBounds
  280. //----------------------------------------------------------------------------------------
  281.  
  282. void FW_CPrivPictureRep::GetPictBounds(FW_SRect& bounds) const
  283. {
  284. #ifdef FW_BUILD_MAC
  285.  
  286.     PictInfo pictInfo;
  287.  
  288.     if(::GetPictInfo(fPlatformPict, &pictInfo, 0, 0, 0, 0) != noErr)
  289.     {
  290.         pictInfo.sourceRect = (*fPlatformPict)->picFrame;
  291.     }
  292.  
  293.     bounds.left        = FW_kFixed0;
  294.     bounds.top        = FW_kFixed0;
  295.     bounds.right    = FW_IntToFixed(pictInfo.sourceRect.right - pictInfo.sourceRect.left);
  296.     bounds.bottom    = FW_IntToFixed(pictInfo.sourceRect.bottom - pictInfo.sourceRect.top);
  297.  
  298. #endif
  299.  
  300. #ifdef FW_BUILD_WIN
  301.     ENHMETAHEADER emh;
  302.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  303.     
  304.     // emh.rclBounds is the bounding rectangle in pixels, computed by GDI
  305.  
  306.     bounds.left        = FW_IntToFixed((int) emh.rclBounds.left);
  307.     bounds.top        = FW_IntToFixed((int) emh.rclBounds.top);
  308.     bounds.right    = FW_IntToFixed((int) emh.rclBounds.right);
  309.     bounds.bottom    = FW_IntToFixed((int) emh.rclBounds.bottom);
  310. #endif
  311. }
  312.  
  313. //----------------------------------------------------------------------------------------
  314. //    FW_CPrivPictureRep::GetPictBoundsGC
  315. //----------------------------------------------------------------------------------------
  316.  
  317. void FW_CPrivPictureRep::GetPictBoundsGC(Environment* ev, FW_SGraphicContext& gc, FW_SRect& bounds) const
  318. {    
  319. #ifdef FW_BUILD_MAC
  320.     FW_SPoint size;
  321.     
  322.     FW_SRect pictureBounds;
  323.     GetPictBounds(pictureBounds);
  324.     const long width = FW_FixedToInt(pictureBounds.right - pictureBounds.left);
  325.     const long height = FW_FixedToInt(pictureBounds.bottom - pictureBounds.top);
  326.     
  327.     FW_PrivGC_DeviceToLogicalSize(ev, gc, width, height, size);
  328.     
  329.     // Let go if error    
  330.     bounds.left        =    FW_kFixed0;
  331.     bounds.top        =     FW_kFixed0;
  332.     bounds.right    =     size.x;
  333.     bounds.bottom    =    size.y;
  334. #endif
  335.  
  336. #ifdef FW_BUILD_WIN
  337.     ENHMETAHEADER emh;
  338.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  339.  
  340.     // emh.rclFrame is the bounding rectangle as specified by the creator, in 0.01 mm units
  341.  
  342.     HDC hDC = gc.fGraphicDevice->GetPlatformCanvas();
  343.  
  344.     int xRes = ::GetDeviceCaps(hDC, LOGPIXELSX);
  345.     int yRes = ::GetDeviceCaps(hDC, LOGPIXELSY);
  346.  
  347.     FW_CPlatformRect plfmBounds;
  348.  
  349.     plfmBounds.left        = emh.rclFrame.left        * xRes / 2540;
  350.     plfmBounds.top        = emh.rclFrame.top        * yRes / 2540;
  351.     plfmBounds.right    = emh.rclFrame.right    * xRes / 2540;
  352.     plfmBounds.bottom    = emh.rclFrame.bottom    * yRes / 2540;
  353.  
  354.     FW_PrivGC_DeviceToLogicalRect(ev, gc, plfmBounds, bounds);
  355.     // Let go if error    
  356. #endif
  357. }
  358.  
  359. //----------------------------------------------------------------------------------------
  360. //    FW_CPrivPictureRep::GetPlatformPict
  361. //----------------------------------------------------------------------------------------
  362.  
  363. FW_PlatformPict    FW_CPrivPictureRep::GetPlatformPict() const
  364. {
  365.     return fPlatformPict;
  366. }
  367.  
  368. //----------------------------------------------------------------------------------------
  369. //    FW_CPrivPictureRep::IsPlatformPictOrphan
  370. //----------------------------------------------------------------------------------------
  371.  
  372. FW_Boolean FW_CPrivPictureRep::IsPlatformPictOrphan() const
  373. {
  374.     return !fOwnPicture;
  375. }
  376.  
  377. //----------------------------------------------------------------------------------------
  378. //    FW_CPrivPictureRep::OrphanPlatformPict
  379. //----------------------------------------------------------------------------------------
  380.  
  381. FW_PlatformPict    FW_CPrivPictureRep::OrphanPlatformPict()
  382. {
  383.     FW_ASSERT(fOwnPicture);        // Cannot orphan twice
  384.     fOwnPicture = FALSE;
  385.     return fPlatformPict;
  386. }
  387.  
  388. //----------------------------------------------------------------------------------------
  389. //    FW_CPrivPictureRep::SetPlatformPict
  390. //----------------------------------------------------------------------------------------
  391.  
  392. void FW_CPrivPictureRep::SetPlatformPict(FW_PlatformPict newPict)
  393. {
  394.     if (fPlatformPict != newPict)
  395.     {
  396.         PrivDisposePict();
  397.         fPlatformPict = newPict;
  398.     }
  399.     
  400.     fOwnPicture = FALSE;
  401. }
  402.  
  403. //----------------------------------------------------------------------------------------
  404. //    FW_CPrivPictureRep::AdoptPlatformPict
  405. //----------------------------------------------------------------------------------------
  406.  
  407. void FW_CPrivPictureRep::AdoptPlatformPict(FW_PlatformPict newPict)
  408. {
  409.     SetPlatformPict(newPict);
  410.     fOwnPicture = TRUE;
  411. }
  412.  
  413. #ifdef FW_BUILD_MAC
  414. //----------------------------------------------------------------------------------------
  415. //    FW_CPrivPictureRep::MacLock
  416. //----------------------------------------------------------------------------------------
  417.  
  418. void FW_CPrivPictureRep::MacLock()
  419. {
  420.     FW_ASSERT(fPlatformPict != NULL);
  421.  
  422.     if (++ fMacLockCount == 1)
  423.         FW_CMemoryManager::LockSystemHandle((FW_PlatformHandle)fPlatformPict);
  424. }
  425. #endif
  426.  
  427. #ifdef FW_BUILD_MAC
  428. //----------------------------------------------------------------------------------------
  429. //    FW_CPrivPictureRep::MacUnlock
  430. //----------------------------------------------------------------------------------------
  431.  
  432. void FW_CPrivPictureRep::MacUnlock()
  433. {
  434.     if (-- fMacLockCount == 0)
  435.         FW_CMemoryManager::UnlockSystemHandle((FW_PlatformHandle)fPlatformPict);    
  436. }
  437. #endif
  438.  
  439. //----------------------------------------------------------------------------------------
  440. //    FW_CPrivPictureRep::PrivReadFrom
  441. //----------------------------------------------------------------------------------------
  442.  
  443. void FW_CPrivPictureRep::PrivReadFrom(FW_CReadableStream& stream)
  444. {
  445. #ifdef FW_BUILD_MAC
  446.     unsigned long picSize;
  447.     stream >> picSize;
  448.     
  449.     fPlatformPict = (FW_PlatformPict) FW_CMemoryManager::AllocateSystemHandle(picSize);
  450.             
  451.     MacLock();
  452.     
  453.     FW_TRY
  454.     {
  455.         stream.Read(*fPlatformPict, picSize);
  456.     }
  457.     FW_CATCH_BEGIN
  458.     FW_CATCH_EVERYTHING()
  459.     {
  460.         MacUnlock();
  461.         ::DisposeHandle((Handle)fPlatformPict);
  462.         fPlatformPict = NULL;
  463.         FW_THROW_SAME();
  464.     }
  465.     FW_CATCH_END
  466.  
  467.     MacUnlock();
  468. #endif
  469. #ifdef FW_BUILD_WIN
  470.     HENHMETAFILE metafile = NULL;
  471.  
  472.     // Check if there is an Aldus metafile header
  473.     SAldusHeader aldusHeader;
  474.     stream.Read(&aldusHeader, sizeof(aldusHeader));
  475.     if(aldusHeader.key == kAldusKey)
  476.     {
  477.         // ----- This is an Aldus format metafile
  478.  
  479.         // Read the header
  480.         METAHEADER mfHeader;
  481.         stream.Read(&mfHeader, sizeof(mfHeader));
  482.  
  483.         // Read the bits
  484.         size_t bitsSize = mfHeader.mtSize * 2L;
  485.         BYTE* bitsBuf = new BYTE[bitsSize];
  486.         
  487.         FW_TRY
  488.         {
  489.             FW_CMemoryManager::CopyMemory(&mfHeader, bitsBuf, sizeof(mfHeader));
  490.             stream.Read(bitsBuf + sizeof(mfHeader), bitsSize - sizeof(mfHeader));
  491.         }
  492.         FW_CATCH_BEGIN
  493.         FW_CATCH_EVERYTHING()
  494.         {
  495.             delete[] bitsBuf;
  496.             FW_THROW_SAME();
  497.         }
  498.         FW_CATCH_END
  499.  
  500.         // Convert an Aldus (Win16) metafile to a Win32 Enhanced Metafile
  501.         METAFILEPICT mfPict;
  502.         mfPict.mm = MM_ANISOTROPIC;
  503.         mfPict.xExt = (aldusHeader.bbox.right - aldusHeader.bbox.left) * 2540 / aldusHeader.inch;
  504.         mfPict.yExt = (aldusHeader.bbox.bottom - aldusHeader.bbox.top) * 2540 / aldusHeader.inch;
  505.  
  506.         metafile = ::SetWinMetaFileBits(bitsSize, bitsBuf, NULL, &mfPict);
  507.         delete[] bitsBuf;
  508.     }
  509.     else
  510.     {
  511.         // ----- Not an Aldus metafile, try Win32 Enhanced metafile
  512.  
  513.         // Read the header
  514.         ENHMETAHEADER enhHeader;
  515.         FW_CMemoryManager::CopyMemory(&aldusHeader, &enhHeader, sizeof(aldusHeader));
  516.         stream.Read((char*) &enhHeader + sizeof(aldusHeader), sizeof(enhHeader) - sizeof(aldusHeader));
  517.  
  518.         // Verify the header
  519.         if(enhHeader.iType == EMR_HEADER || enhHeader.nSize == sizeof(enhHeader))
  520.         {
  521.             // Read the bits
  522.             size_t bitsSize = enhHeader.nBytes;
  523.             BYTE* bitsBuf = new BYTE[bitsSize];
  524.             FW_TRY
  525.             {
  526.                 FW_CMemoryManager::CopyMemory(&enhHeader, bitsBuf, sizeof(enhHeader));
  527.                 stream.Read(bitsBuf + sizeof(enhHeader), bitsSize - sizeof(enhHeader));
  528.             }
  529.             FW_CATCH_BEGIN
  530.             FW_CATCH_EVERYTHING()
  531.             {
  532.                 delete[] bitsBuf;
  533.                 FW_THROW_SAME();
  534.             }
  535.             FW_CATCH_END
  536.     
  537.             // Create a metafile and set the bits
  538.              metafile = ::SetEnhMetaFileBits(bitsSize, bitsBuf);
  539.             delete[] bitsBuf;
  540.         }
  541.     }
  542.  
  543.     if(metafile == NULL)
  544.         FW_Failure(FW_xInvalidPictureData);
  545.  
  546.     // Save metafile info
  547.     AdoptPlatformPict(metafile);
  548. #endif
  549. }
  550.  
  551. //----------------------------------------------------------------------------------------
  552. //    FW_CPrivPictureRep::PrivDisposePict
  553. //----------------------------------------------------------------------------------------
  554.  
  555. void FW_CPrivPictureRep::PrivDisposePict()
  556. {
  557.     if (fOwnPicture && fPlatformPict != NULL)
  558.     {
  559. #ifdef FW_BUILD_MAC
  560.         ::KillPicture(fPlatformPict);
  561. #endif
  562. #ifdef FW_BUILD_WIN
  563.         ::DeleteEnhMetaFile(fPlatformPict);
  564. #endif
  565.     }
  566.  
  567.     fPlatformPict = NULL;
  568. }
  569.