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 / PRBitmap.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  35.9 KB  |  1,350 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRBitmap.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 PRBITMAP_H
  25. #include "PRBitmap.h"
  26. #endif
  27.  
  28. #ifndef SLGC_H
  29. #include "SLGC.h"
  30. #endif
  31.  
  32. #ifndef FWWINRES_H
  33. #include "FWWinRes.h"
  34. #endif
  35.  
  36. #ifndef FWSTRMRW_H
  37. #include "FWStrmRW.h"
  38. #endif
  39.  
  40. #ifndef FWRESOUR_H
  41. #include "FWResour.h"
  42. #endif
  43.  
  44. #ifndef FWGRUTIL_H
  45. #include "FWGrUtil.h"
  46. #endif
  47.  
  48. #ifndef FWPALETE_H
  49. #include "FWPalete.h"
  50. #endif
  51.  
  52. #ifndef FWSOMENV_H
  53. #include "FWSOMEnv.h"
  54. #endif
  55.  
  56. #ifndef PRGRUTIL_H
  57. #include "PRGrUtil.h"
  58. #endif
  59.  
  60. #ifndef   FWMEMHLP_H
  61. #include "FWMemHlp.h"
  62. #endif
  63.  
  64. #ifndef FWEXCEPT_H
  65. #include "FWExcept.h"
  66. #endif
  67.  
  68. #if defined(FW_BUILD_WIN) && !defined(FWWINDIB_H)
  69. #include "FWWinDIB.h"
  70. #endif
  71.  
  72. #if defined(FW_BUILD_MAC) && !defined(__PICTUTILS__)
  73. #include <PictUtils.h>
  74. #endif
  75.  
  76. #ifndef PRPICTUR_H
  77. #include "PRPictur.h"
  78. #endif
  79.  
  80. //========================================================================================
  81. //    RunTime Info
  82. //========================================================================================
  83.  
  84. #ifdef FW_BUILD_MAC
  85. #pragma segment FW_Graphics
  86. #endif
  87.  
  88. FW_DEFINE_AUTO(FW_CPrivBitmapRep)
  89.  
  90. //========================================================================================
  91. // CLASS FW_CPrivBitmapRep
  92. //========================================================================================
  93.  
  94. #ifdef FW_BUILD_MAC
  95.  
  96. // Special Russian value swapping: uses no temporary
  97.  
  98. #define SWAP(a, b)     do { (a) = (a) ^ (b);    (b) = (a) ^ (b); (a) = (a) ^ (b); } while(0)
  99.  
  100. //----------------------------------------------------------------------------------------
  101. //    MacRepackResourceRow
  102. //----------------------------------------------------------------------------------------
  103.  
  104. static void MacRepackResourceRow(char* curBuffer, short bitDepth, short resRowBytes)
  105. {
  106.     short pixelBytes = bitDepth / 8;
  107.  
  108.     if(pixelBytes == 2)
  109.     {
  110.         do
  111.         {
  112.             SWAP(curBuffer[0], curBuffer[1]);
  113.         }
  114.         while((resRowBytes -= pixelBytes) > 0);
  115.     }
  116.     else if(pixelBytes == 4)
  117.     {
  118.         do
  119.         {
  120.             SWAP(curBuffer[0], curBuffer[3]);
  121.             SWAP(curBuffer[1], curBuffer[2]);
  122.         }
  123.         while((resRowBytes -= pixelBytes) > 0);
  124.     }
  125. }
  126.  
  127. //----------------------------------------------------------------------------------------
  128. //    MacRepackValue
  129. //----------------------------------------------------------------------------------------
  130.  
  131. static void MacRepackValue(short* s)
  132. {
  133.     char* c = (char*) s;
  134.     SWAP(c[0], c[1]);
  135. }
  136.  
  137. static void MacRepackValue(unsigned short* s)
  138. {
  139.     char* c = (char*) s;
  140.     SWAP(c[0], c[1]);
  141. }
  142.  
  143. static void MacRepackValue(long* l)
  144. {
  145.     char* c = (char*) l;
  146.     SWAP(c[0], c[3]);
  147.     SWAP(c[1], c[2]);
  148. }
  149.  
  150. static void MacRepackValue(unsigned long* l)
  151. {
  152.     char* c = (char*) l;
  153.     SWAP(c[0], c[3]);
  154.     SWAP(c[1], c[2]);
  155. }
  156.  
  157. #endif
  158.  
  159. //----------------------------------------------------------------------------------------
  160. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  161. //----------------------------------------------------------------------------------------
  162. // From image: will own the bitmap
  163.  
  164. FW_CPrivBitmapRep::FW_CPrivBitmapRep(short width,  short height,
  165.                                     short pixelSize, FW_Palette palette,
  166.                                     void* image, long imageSize, short rowBytes) :
  167.     fOwnBitmap(TRUE),
  168.     fPlatformBitmap(NULL)
  169. {
  170. #ifdef FW_BUILD_MAC
  171.     fLockCount = 0;
  172.     fPixMapHandle = NULL;
  173. #endif
  174. #ifdef FW_BUILD_WIN
  175.     fUserColorDepth = 0;
  176.     fWinPalette = NULL;
  177. #endif
  178.  
  179.     PrivMakeBitmap(width, height, pixelSize, palette);
  180.         
  181.     if (image != NULL)
  182.         SetImage(image, imageSize, rowBytes);
  183.         
  184.     FW_END_CONSTRUCTOR
  185. }
  186.  
  187. //----------------------------------------------------------------------------------------
  188. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  189. //----------------------------------------------------------------------------------------
  190. // From platform bitmap: will not own the bitmap
  191.  
  192. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_PlatformBitmap platformBitmap) :
  193.     fOwnBitmap(FALSE),
  194.     fPlatformBitmap(platformBitmap)
  195. {
  196. #ifdef FW_BUILD_MAC
  197.     fLockCount = 0;
  198.     fPixMapHandle = NULL;
  199. #endif
  200. #ifdef FW_BUILD_WIN
  201.     fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
  202.     fWinPalette = NULL;
  203. #endif
  204.  
  205.     FW_END_CONSTRUCTOR
  206. }
  207.  
  208. //----------------------------------------------------------------------------------------
  209. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  210. //----------------------------------------------------------------------------------------
  211. // From resources: will own the bitmap
  212.  
  213. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_OResourceFile* resourceFile, FW_ResourceID resID) :
  214.     fOwnBitmap(TRUE),
  215.     fPlatformBitmap(NULL)
  216. {
  217. #ifdef FW_BUILD_MAC
  218.     fLockCount = 0;
  219.     fPixMapHandle = NULL;
  220. #endif
  221. #ifdef FW_BUILD_WIN
  222.     fUserColorDepth = 0;
  223.     fWinPalette = NULL;
  224. #endif
  225.  
  226.     fPlatformBitmap = NULL;
  227.  
  228.     FW_SOMEnvironment ev;
  229.     FW_PResource resource(ev, resourceFile, resID, FW_kBitmap);
  230.     FW_PResourceSink sink(ev, resource);
  231.     FW_CReadableStream stream(sink);
  232.  
  233. #ifdef FW_BUILD_WIN
  234.     PrivReadFromStream(stream, FALSE);
  235. #endif
  236. #ifdef FW_BUILD_MAC
  237.     PrivReadFromStream(stream, TRUE);
  238. #endif
  239.     
  240.     FW_END_CONSTRUCTOR
  241. }
  242.  
  243. //----------------------------------------------------------------------------------------
  244. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  245. //----------------------------------------------------------------------------------------
  246. // From another bitmap: will own the bitmap (a copy is made)
  247.  
  248. FW_CPrivBitmapRep::FW_CPrivBitmapRep(const FW_CPrivBitmapRep& bitmap, const FW_SRect& srcRect) :
  249.     fOwnBitmap(TRUE),
  250.     fPlatformBitmap(NULL)    
  251. {
  252. #ifdef FW_BUILD_MAC
  253.     fLockCount = 0;
  254.     fPixMapHandle = NULL;
  255. #endif
  256. #ifdef FW_BUILD_WIN
  257.     fUserColorDepth = 0;
  258.     fWinPalette = NULL;
  259. #endif
  260.  
  261.     FW_CRect bounds;
  262.     bitmap.GetBitmapBounds(bounds);
  263.     
  264.     FW_CRect clipRect = srcRect;
  265.  
  266.     if (clipRect.left < FW_kFixed0) 
  267.         clipRect.left = FW_kFixed0;
  268.     else if (clipRect.left > bounds.right) 
  269.         clipRect.left = bounds.right;
  270.         
  271.     if (clipRect.top < FW_kFixed0) 
  272.         clipRect.top = FW_kFixed0;
  273.     else if (clipRect.top > bounds.bottom) 
  274.         clipRect.top = bounds.bottom;
  275.     
  276.     if (clipRect.right > bounds.right) 
  277.         clipRect.right = bounds.right;
  278.     else if (clipRect.right < clipRect.left)
  279.         clipRect.right = clipRect.left;
  280.     
  281.     if (clipRect.bottom > bounds.bottom) 
  282.         clipRect.bottom = bounds.bottom;
  283.     else if (clipRect.bottom < clipRect.top) 
  284.         clipRect.bottom = clipRect.top;
  285.  
  286.     FW_CRect dstRect(FW_kFixed0, FW_kFixed0, clipRect.right - clipRect.left, clipRect.bottom - clipRect.top);
  287.  
  288.     short width, height, rowBytes, pixelSize;
  289.     bitmap.GetBitmapInfo(width, height, rowBytes, pixelSize);
  290.     
  291.     FW_Palette palette = bitmap.GetPalette();
  292.     PrivMakeBitmap(
  293.         FW_FixedToInt(clipRect.right - clipRect.left),
  294.         FW_FixedToInt(clipRect.bottom - clipRect.top), pixelSize, palette);
  295.  
  296.     bitmap.CopyPixels(*this, clipRect, dstRect);
  297.     
  298.     FW_END_CONSTRUCTOR
  299. }
  300.  
  301. //----------------------------------------------------------------------------------------
  302. //    FW_CPrivBitmapRep::~FW_CPrivBitmapRep
  303. //----------------------------------------------------------------------------------------
  304.  
  305. FW_CPrivBitmapRep::~FW_CPrivBitmapRep()
  306. {
  307.     PrivDisposeBitmap();
  308. }
  309.  
  310. //----------------------------------------------------------------------------------------
  311. //    FW_CPrivBitmapRep::IsEqual
  312. //----------------------------------------------------------------------------------------
  313.  
  314. FW_Boolean FW_CPrivBitmapRep::IsEqual(const FW_CPrivBitmapRep& bitmap) const
  315. {
  316.     return fPlatformBitmap == bitmap.fPlatformBitmap;
  317. }
  318.  
  319. //----------------------------------------------------------------------------------------
  320. //    FW_CPrivBitmapRep::Write
  321. //----------------------------------------------------------------------------------------
  322.  
  323. void FW_CPrivBitmapRep::Write(FW_CWritableStream& stream, FW_Boolean bDIBFileHeader)
  324. {
  325. #ifdef FW_BUILD_MAC
  326.     // Lock the GWorld pixmap
  327.     FW_CPrivMacPixelLock lock(this);
  328.     PixMapHandle pmh = lock.GetPixMapHandle();
  329.  
  330.     short        width        = (*pmh)->bounds.right;
  331.     short        height         = (*pmh)->bounds.bottom;
  332.     short        bitDepth    = (*pmh)->pixelSize;
  333.     
  334.     short        resRowBytes    = ((width * bitDepth + 31) & ~31) / 8;
  335.     short        memRowBytes    = (*pmh)->rowBytes & 0x7FFF;
  336.  
  337.     FW_ASSERT(resRowBytes <= memRowBytes);
  338.  
  339.     long imageSize = height * resRowBytes;
  340.  
  341.     // Determine color table size
  342.     int colorTableCount = bitDepth < 16 ? 1 << bitDepth : 0;
  343.     int colorTableSize  = colorTableCount * sizeof(RGBQUAD);
  344.  
  345.     // Create a file header
  346.     if(bDIBFileHeader)
  347.     {
  348.         BITMAPFILEHEADER bmfh;
  349.         bmfh.bfType                = FW_kWinBitmapSignature;
  350.         bmfh.bfSize                = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  351.                                 colorTableSize + imageSize;
  352.         bmfh.bfReserved1        = 0;
  353.         bmfh.bfReserved2        = 0;
  354.         bmfh.bfOffBits            = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
  355.                                 colorTableSize;
  356.         
  357.         // Byte-swap and write it out
  358.         
  359.         MacRepackValue(&bmfh.bfType);
  360.         MacRepackValue(&bmfh.bfSize);
  361.         MacRepackValue(&bmfh.bfReserved1);
  362.         MacRepackValue(&bmfh.bfReserved2);
  363.         MacRepackValue(&bmfh.bfOffBits);
  364.         
  365.         stream.Write(&bmfh, sizeof(bmfh));
  366.     }
  367.  
  368.     // Create a DIB header
  369.  
  370.     BITMAPINFOHEADER bmih;
  371.  
  372.     bmih.biSize                = sizeof(BITMAPINFOHEADER);
  373.     bmih.biWidth            = width;
  374.     bmih.biHeight            = height;
  375.     bmih.biPlanes            = 1;
  376.     bmih.biBitCount            = bitDepth;
  377.     
  378.     bmih.biCompression        = 0;
  379.     bmih.biSizeImage        = imageSize;
  380.  
  381.     bmih.biXPelsPerMeter    = 0;
  382.     bmih.biYPelsPerMeter    = 0;
  383.     bmih.biClrUsed            = 0;
  384.     bmih.biClrImportant        = 0;
  385.     
  386.     // Byte-swap and write it out
  387.  
  388.     MacRepackValue(&bmih.biSize);
  389.     MacRepackValue(&bmih.biWidth);
  390.     MacRepackValue(&bmih.biHeight);
  391.     MacRepackValue(&bmih.biPlanes);
  392.     MacRepackValue(&bmih.biBitCount);
  393.     MacRepackValue(&bmih.biCompression);
  394.     MacRepackValue(&bmih.biSizeImage);
  395.     MacRepackValue(&bmih.biXPelsPerMeter);
  396.     MacRepackValue(&bmih.biYPelsPerMeter);
  397.     MacRepackValue(&bmih.biClrUsed);
  398.     MacRepackValue(&bmih.biClrImportant);
  399.  
  400.     stream.Write(&bmih, sizeof(bmih));
  401.  
  402.     // Write the color table (if applicable)
  403.     if(colorTableCount != 0)
  404.     {
  405.         CTabHandle cTabHandle = (*pmh)->pmTable;
  406.         FW_ASSERT(colorTableCount <= (*cTabHandle)->ctSize + 1);    // ctSize is count - 1!
  407.  
  408.         for(int i = 0; i < colorTableCount; ++i)
  409.         {
  410.             RGBQUAD quad;
  411.  
  412.             quad.rgbBlue        = (*cTabHandle)->ctTable[i].rgb.blue    >> 8;
  413.             quad.rgbGreen        = (*cTabHandle)->ctTable[i].rgb.green    >> 8;
  414.             quad.rgbRed            = (*cTabHandle)->ctTable[i].rgb.red        >> 8;
  415.             quad.rgbReserved    = 0;
  416.  
  417.             stream.Write(&quad, sizeof(quad));
  418.         }
  419.     }
  420.  
  421.     // Finally, do the bits (upside-down)
  422.     char* bitsBuffer = new char[memRowBytes];
  423.     
  424.     FW_TRY
  425.     {
  426.         const char* baseBuffer = ::GetPixBaseAddr(pmh);
  427.         const char* currBuffer = baseBuffer + memRowBytes * (height - 1);
  428.         
  429.         for(int row = height - 1; row >= 0; -- row, currBuffer -= memRowBytes)
  430.         {
  431.             ::BlockMove(currBuffer, bitsBuffer, resRowBytes);
  432.             MacRepackResourceRow(bitsBuffer, bitDepth, resRowBytes);
  433.             stream.Write(bitsBuffer, resRowBytes);
  434.         }
  435.     }
  436.     FW_CATCH_BEGIN
  437.     FW_CATCH_EVERYTHING()
  438.     {
  439.         delete[] bitsBuffer;
  440.         FW_THROW_SAME();
  441.     }
  442.     FW_CATCH_END
  443.     delete[] bitsBuffer;
  444. #endif
  445.  
  446. #ifdef FW_BUILD_WIN
  447.     // Convert to DIB first; use the color depth the user wanted
  448.     FW_WinDIB dib = FW_DIBConvertFromBitmap(fPlatformBitmap, fUserColorDepth, fWinPalette);
  449.     
  450.     FW_TRY
  451.     {
  452.         // Write out the DIB
  453.         FW_DIBSaveToStream(stream, dib, bDIBFileHeader);
  454.     }
  455.     FW_CATCH_BEGIN
  456.     FW_CATCH_EVERYTHING()
  457.     {
  458.         FW_DIBFree(dib);
  459.         FW_THROW_SAME();
  460.     }
  461.     FW_CATCH_END
  462.  
  463.     // Free the DIB
  464.     FW_DIBFree(dib);
  465. #endif
  466. }
  467.  
  468. //----------------------------------------------------------------------------------------
  469. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  470. //----------------------------------------------------------------------------------------
  471. // From a stream: will own the bitmap
  472.  
  473. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_CReadableStream& stream, FW_Boolean bDIBFileHeader) :
  474.     fOwnBitmap(TRUE),
  475.     fPlatformBitmap(NULL)
  476. {
  477. #ifdef FW_BUILD_MAC
  478.     fLockCount = 0;
  479.     fPixMapHandle = NULL;
  480. #endif
  481. #ifdef FW_BUILD_WIN
  482.     fUserColorDepth = 0;
  483.     fWinPalette = NULL;
  484. #endif
  485.  
  486.     PrivReadFromStream(stream, bDIBFileHeader);
  487. }
  488.  
  489. //----------------------------------------------------------------------------------------
  490. //    FW_CPrivBitmapRep::GetPlatformBitmap
  491. //----------------------------------------------------------------------------------------
  492.  
  493. FW_PlatformBitmap  FW_CPrivBitmapRep::GetPlatformBitmap() const
  494. {
  495.     return fPlatformBitmap;
  496. }
  497.  
  498. //----------------------------------------------------------------------------------------
  499. //    FW_CPrivBitmapRep::IsPlatformBitmapOrphan
  500. //----------------------------------------------------------------------------------------
  501.  
  502. FW_Boolean FW_CPrivBitmapRep::IsPlatformBitmapOrphan() const
  503. {
  504.     return !fOwnBitmap;
  505. }
  506.  
  507. //----------------------------------------------------------------------------------------
  508. //    FW_CPrivBitmapRep::OrphanPlatformBitmap
  509. //----------------------------------------------------------------------------------------
  510.  
  511. FW_PlatformBitmap  FW_CPrivBitmapRep::OrphanPlatformBitmap()
  512. {
  513.     FW_ASSERT(fOwnBitmap);        // Only orphan once
  514.     fOwnBitmap = FALSE;
  515.     return fPlatformBitmap;
  516. }
  517.  
  518. //----------------------------------------------------------------------------------------
  519. //    FW_CPrivBitmapRep::SetPlatformBitmap
  520. //----------------------------------------------------------------------------------------
  521.  
  522. void FW_CPrivBitmapRep::SetPlatformBitmap(FW_PlatformBitmap newBitmap)
  523. {
  524.     if (fPlatformBitmap != newBitmap)
  525.     {
  526.         PrivDisposeBitmap();
  527.         fPlatformBitmap = newBitmap;
  528.     }
  529.     
  530.     fOwnBitmap = FALSE;
  531. }
  532.  
  533. //----------------------------------------------------------------------------------------
  534. //    FW_CPrivBitmapRep::AdoptPlatformBitmap
  535. //----------------------------------------------------------------------------------------
  536.  
  537. void FW_CPrivBitmapRep::AdoptPlatformBitmap(FW_PlatformBitmap newBitmap)
  538. {
  539.     SetPlatformBitmap(newBitmap);
  540.     fOwnBitmap = TRUE;
  541. }
  542.  
  543. //----------------------------------------------------------------------------------------
  544. //    FW_CPrivBitmapRep::GetPalette
  545. //----------------------------------------------------------------------------------------
  546.  
  547. FW_Palette FW_CPrivBitmapRep::GetPalette() const
  548. {
  549. #ifdef FW_BUILD_MAC
  550.     FW_CPrivMacPixelLock lock((FW_HBitmap)this);
  551.     PixMapHandle pmh = lock.GetPixMapHandle();
  552.     return (*pmh)->pmTable;
  553. #endif
  554. #ifdef FW_BUILD_WIN
  555.     return fWinPalette;
  556. #endif
  557. }
  558.  
  559. //----------------------------------------------------------------------------------------
  560. //    FW_CPrivBitmapRep::SetPalette
  561. //----------------------------------------------------------------------------------------
  562.  
  563. void FW_CPrivBitmapRep::SetPalette(FW_Palette palette)
  564. {
  565. #ifdef FW_BUILD_MAC
  566.     FW_CPrivMacPixelLock lock(this);
  567.     PixMapHandle pmh = lock.GetPixMapHandle();
  568.     CTabHandle oldTable = (*pmh)->pmTable;
  569.     (*pmh)->pmTable = palette;
  570.     ::DisposeHandle((Handle)oldTable);
  571. #endif
  572. #ifdef FW_BUILD_WIN
  573.     if (fWinPalette != NULL)
  574.         ::DeleteObject(fWinPalette);
  575.     fWinPalette = palette;
  576. #endif
  577. }
  578.  
  579. //----------------------------------------------------------------------------------------
  580. //    FW_CPrivBitmapRep::GetBitmapInfo
  581. //----------------------------------------------------------------------------------------
  582.  
  583. void FW_CPrivBitmapRep::GetBitmapInfo(
  584.         short& width,
  585.         short& height,
  586.         short& rowBytes,
  587.         short& pixelSize) const
  588. {
  589. #ifdef FW_BUILD_MAC
  590.     PixMapHandle pixMap = ::GetGWorldPixMap(fPlatformBitmap);
  591.  
  592.     width        = (*pixMap)->bounds.right - (*pixMap)->bounds.left;
  593.     height        = (*pixMap)->bounds.bottom - (*pixMap)->bounds.top;
  594.     rowBytes    = (*pixMap)->rowBytes & 0x7FFF;
  595.     pixelSize    = (*pixMap)->pixelSize;
  596. #endif
  597.  
  598. #ifdef FW_BUILD_WIN
  599.     BITMAP bm;
  600.     ::GetObject(fPlatformBitmap, sizeof(bm), &bm);
  601.  
  602.     width        = (short) bm.bmWidth;
  603.     height        = (short) bm.bmHeight;
  604.     rowBytes    = (short) bm.bmWidthBytes;
  605.     pixelSize    = fUserColorDepth;            // The actual DDB pixel size may differ
  606. #endif
  607. }
  608.  
  609. //----------------------------------------------------------------------------------------
  610. //    FW_CPrivBitmapRep::GetBitmapBoundsGC
  611. //----------------------------------------------------------------------------------------
  612.  
  613. void FW_CPrivBitmapRep::GetBitmapBoundsGC(Environment* ev, FW_SGraphicContext& gc, FW_SRect& bounds) const
  614. {
  615.     short width, height,rowBytes, pixelSize;
  616.     GetBitmapInfo(width, height, rowBytes, pixelSize);
  617.         
  618.     FW_CPoint size;
  619.     FW_PrivGC_DeviceToLogicalSize(ev, gc, width, height, size);
  620.     // let go if error
  621.     
  622.     bounds.left        = FW_kFixed0;
  623.     bounds.top        = FW_kFixed0;
  624.     bounds.right    = size.x;
  625.     bounds.bottom    = size.y;
  626. }
  627.  
  628. //----------------------------------------------------------------------------------------
  629. //    FW_CPrivBitmapRep::GetBitmapBounds
  630. //----------------------------------------------------------------------------------------
  631.  
  632. void FW_CPrivBitmapRep::GetBitmapBounds(FW_SRect& bounds) const
  633. {
  634.     short width, height,rowBytes, pixelSize;
  635.     GetBitmapInfo(width, height, rowBytes, pixelSize);
  636.  
  637.     bounds.left     = FW_IntToFixed(0);
  638.     bounds.top        = FW_IntToFixed(0);
  639.     bounds.right    = FW_IntToFixed(width);
  640.     bounds.bottom    = FW_IntToFixed(height);
  641. }
  642.  
  643. //----------------------------------------------------------------------------------------
  644. //    FW_CPrivBitmapRep::GetPixelColor
  645. //----------------------------------------------------------------------------------------
  646.  
  647. void FW_CPrivBitmapRep::GetPixelColor(short horiz,
  648.                                     short vert,
  649.                                     FW_CColor& color) const
  650. {
  651. #ifdef FW_BUILD_MAC
  652.     CGrafPtr     curPort;
  653.     GDHandle     gdh;
  654.     RGBColor    platformColor;
  655.     ::GetGWorld(&curPort, &gdh);
  656.     ::SetGWorld(GetPlatformBitmap(), NULL);
  657.     ::GetCPixel(horiz, vert, &platformColor);
  658.     ::SetGWorld(curPort, gdh);    
  659.     
  660.     color = platformColor;
  661. #endif
  662.     
  663. #ifdef FW_BUILD_WIN
  664.         // needs to be implemented
  665. #endif
  666. }
  667.  
  668. //----------------------------------------------------------------------------------------
  669. //    FW_CPrivBitmapRep::SetPixelColor
  670. //----------------------------------------------------------------------------------------
  671.  
  672. void FW_CPrivBitmapRep::SetPixelColor(short horiz,
  673.                                     short vert,
  674.                                     const FW_CColor& color)
  675. {
  676. #ifdef FW_BUILD_MAC
  677.     CGrafPtr     curPort;
  678.     GDHandle    gdh;
  679.     RGBColor    platformColor(color);
  680.     ::GetGWorld(&curPort, &gdh);
  681.     ::SetGWorld(GetPlatformBitmap(), NULL);
  682.     ::SetCPixel(horiz, vert, &platformColor);
  683.     ::SetGWorld(curPort, gdh);
  684. #endif
  685.  
  686. #ifdef FW_BUILD_WIN
  687.         // needs to be implemented
  688. #endif
  689. }
  690.  
  691. //----------------------------------------------------------------------------------------
  692. //    FW_CPrivBitmapRep::ChangeBitmap
  693. //----------------------------------------------------------------------------------------
  694.  
  695. FW_PlatformError FW_CPrivBitmapRep::ChangeBitmap(short         width,
  696.                                     short         height,
  697.                                     short         pixelSize,
  698.                                     FW_Boolean     bScale)
  699. {
  700.     FW_PlatformError error = FW_xNoError;
  701.     
  702. #ifdef FW_BUILD_MAC
  703.     FW_ASSERT(!MacIsPixelsLocked());
  704.     FW_CPlatformRect boundsRect(0, 0, width, height);
  705.     GWorldFlags flags = ::UpdateGWorld(&fPlatformBitmap, pixelSize, &boundsRect, NULL, NULL, bScale ? stretchPix : clipPix);
  706.     if (flags == gwFlagErr)
  707.         error = FW_xGraphicException;
  708. #endif
  709.  
  710. #ifdef FW_BUILD_WIN
  711.     // Determine color depth for the DDB
  712.     short bmNewPlanes = 1, bmNewBitsPixel = 1;
  713.     if(pixelSize != 1)
  714.         FW_PrivWinGetDisplayColorInfo(bmNewPlanes, bmNewBitsPixel);
  715.         
  716.     // Get the current bitmap depth
  717.     BITMAP bm;
  718.     ::GetObject(fPlatformBitmap, sizeof(bm), &bm);
  719.     
  720.     if(bm.bmPlanes != bmNewPlanes || bm.bmBitsPixel != bmNewBitsPixel ||
  721.         bm.bmWidth != width || bm.bmHeight != height)
  722.     {
  723.         // Create a new bitmap        
  724.         HBITMAP bitmap = ::CreateBitmap(width, height, bmNewPlanes, bmNewBitsPixel, NULL);
  725.         if(bitmap != NULL)
  726.         {
  727.             // Copy the bits
  728.             FW_CPlatformRect rectSrc(0, 0, bm.bmWidth, bm.bmHeight);
  729.             FW_CPlatformRect rectDst(0, 0, width, height);
  730.             FW_DDBCopyImage(
  731.                 bitmap, NULL, &rectDst,                 // Even if fWinPalette is not NULL,
  732.                 fPlatformBitmap, NULL, &rectSrc,        //  no color translation is needed here
  733.                 bScale
  734.                     ? FW_kScaleImage
  735.                     : FW_kCropImage);
  736.     
  737.             // Replace the platform bitmap
  738.             AdoptPlatformBitmap(bitmap);
  739.         }
  740.         else
  741.         {
  742.             error = FW_xGraphicException;
  743.         }
  744.     }
  745.  
  746.     // Update the color depth
  747.     if(pixelSize != 0 && error == FW_xNoError)
  748.         fUserColorDepth = pixelSize;
  749.     else
  750.         fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
  751. #endif
  752.  
  753.     return error;
  754. }
  755.  
  756. //----------------------------------------------------------------------------------------
  757. //    FW_CPrivBitmapRep::ChangeBitmap
  758. //----------------------------------------------------------------------------------------
  759.  
  760. FW_PlatformError FW_CPrivBitmapRep::ChangeBitmap(void*         image,
  761.                                     long         imageSize,
  762.                                     short        rowBytes,
  763.                                     short         width,
  764.                                     short         height,
  765.                                     short         pixelSize,
  766.                                     FW_Boolean     bScale)
  767. {    
  768.     FW_ASSERT(image != NULL);
  769.     FW_PlatformError error = ChangeBitmap(width, height, pixelSize, bScale);
  770.     if (error == FW_xNoError)
  771.         error = SetImage(image, imageSize, rowBytes);
  772.     return error;
  773. }
  774.  
  775. //----------------------------------------------------------------------------------------
  776. //    FW_CPrivBitmapRep::SetImage
  777. //----------------------------------------------------------------------------------------
  778.  
  779. FW_PlatformError FW_CPrivBitmapRep::SetImage(void*     image,
  780.                                 long     imageSize,
  781.                                 short    rowBytes)
  782. {
  783.     short bmpHeight, bmpWidth, bmpRowBytes, bmpPixelSize;
  784.     GetBitmapInfo(bmpWidth, bmpHeight, bmpRowBytes, bmpPixelSize);
  785.  
  786.     FW_ASSERT(rowBytes <= bmpRowBytes);
  787.  
  788. #ifdef FW_BUILD_MAC
  789.     FW_CPrivMacPixelLock lock(this);
  790.     PixMapHandle pmh = lock.GetPixMapHandle();
  791.     Ptr baseAddr = ::GetPixBaseAddr(pmh);
  792.     
  793.     if (rowBytes == bmpRowBytes)
  794.     {
  795.         size_t toCopy = bmpHeight * bmpRowBytes;
  796.         if (toCopy > imageSize)
  797.             toCopy = imageSize;
  798.  
  799.         FW_PrimitiveCopyMemory(image, baseAddr, toCopy);
  800.     }
  801.     else
  802.     {
  803.         const char* srcPtr = (const char*) image;
  804.         char* dstPtr = baseAddr;
  805.         
  806.         for (
  807.             int nRow = 0;
  808.             nRow < bmpHeight && imageSize > 0;
  809.             ++nRow, imageSize -= rowBytes, srcPtr += rowBytes, dstPtr += bmpRowBytes
  810.             )
  811.             FW_PrimitiveCopyMemory(srcPtr, dstPtr, rowBytes);
  812.     }
  813. #endif
  814.  
  815. #ifdef FW_BUILD_WIN
  816.     if (rowBytes == bmpRowBytes)
  817.     {
  818.         ::SetBitmapBits(fPlatformBitmap, imageSize, image);
  819.     }
  820.     else
  821.     {
  822.         int nRowCount = imageSize / rowBytes;
  823.         FW_CAcquireTemporaryMemory tempMem(nRowCount * bmpRowBytes);
  824.         
  825.         const char* srcPtr = (const char*) image;
  826.         char* dstPtr = (char*) tempMem.GetPointer();
  827.  
  828.         for (
  829.             int nRow = 0;
  830.             nRow < bmpHeight && imageSize > 0;
  831.             ++nRow, imageSize -= rowBytes, srcPtr += rowBytes, dstPtr += bmpRowBytes
  832.             )
  833.             FW_PrimitiveCopyMemory(srcPtr, dstPtr, rowBytes);
  834.  
  835.         ::SetBitmapBits(fPlatformBitmap, nRowCount * bmpRowBytes, tempMem.GetPointer());
  836.     }
  837. #endif
  838.  
  839.     return FW_xNoError;
  840. }
  841.  
  842. //----------------------------------------------------------------------------------------
  843. //    FW_CPrivBitmapRep::CopyPixels
  844. //----------------------------------------------------------------------------------------
  845.  
  846. FW_PlatformError FW_CPrivBitmapRep::CopyPixels(FW_CPrivBitmapRep& dstBitmap, 
  847.                                     const FW_SRect& boundsSrc, 
  848.                                     const FW_SRect& boundsDst) const
  849. {
  850.     FW_RETURN_ERR_TRY
  851.     {
  852.         FW_CPlatformRect plfmSrcRect = boundsSrc;
  853.         FW_CPlatformRect plfmDstRect = boundsDst;
  854.  
  855. #ifdef FW_BUILD_MAC
  856.         FW_CPrivMacPixelLock srcLock((FW_HBitmap)this);
  857.         PixMapHandle srcPixMap = srcLock.GetPixMapHandle();
  858.     
  859.         FW_CPrivMacPixelLock dstLock(&dstBitmap);
  860.         PixMapHandle dstPixMap = dstLock.GetPixMapHandle();
  861.         
  862.         CGrafPtr     curPort;
  863.         GDHandle     gdh;
  864.         ::GetGWorld(&curPort, &gdh);
  865.         ::SetGWorld(dstBitmap.GetPlatformBitmap(), NULL);
  866.         ::CopyBits((BitMap*)*srcPixMap, (BitMap*)*dstPixMap,  
  867.                     &plfmSrcRect, &plfmDstRect, 
  868.                     srcCopy, NULL);
  869.         ::SetGWorld(curPort, gdh);    
  870. #endif
  871. #ifdef FW_BUILD_WIN
  872.         HBITMAP dstBitmapHandle = dstBitmap.GetPlatformBitmap();
  873.         HPALETTE hDstPalette = dstBitmap.GetPalette();
  874.     
  875.         FW_DDBCopyImage(dstBitmapHandle, hDstPalette, &plfmDstRect,
  876.                         fPlatformBitmap, fWinPalette, &plfmSrcRect,
  877.                         FW_kScaleImage);
  878. #endif
  879.     }
  880.     FW_RETURN_ERR_CATCH
  881. }
  882.  
  883. #ifdef FW_BUILD_MAC
  884.  
  885. //----------------------------------------------------------------------------------------
  886. //    FW_CPrivBitmapRep::FW_CPrivBitmapRep
  887. //----------------------------------------------------------------------------------------
  888. // From a picture: will own the bitmap
  889.  
  890. FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_HPicture picture, FW_SColor fillColor, const FW_SRect& pictPart) :
  891.     fOwnBitmap(TRUE),
  892.     fPlatformBitmap(NULL)
  893. {
  894. #ifdef FW_BUILD_MAC
  895.     fLockCount = 0;
  896.     fPixMapHandle = NULL;
  897. #endif
  898. #ifdef FW_BUILD_WIN
  899.     fUserColorDepth = 0;
  900.     fWinPalette = NULL;
  901. #endif
  902.  
  903.     CGrafPtr curPort;
  904.     GDHandle gdh;
  905.     ::GetGWorld(&curPort, &gdh);
  906.  
  907.     //    It looks like I have to be in a 'valid' port before calling GetPictInfo
  908.     //    I don't know why but if I remove the following three lines I end up with
  909.     //    color problems.
  910.     CGrafPtr screenPort;
  911.     GetCWMgrPort(&screenPort);
  912.     ::SetPort((GrafPtr)screenPort);
  913.  
  914.     FW_PlatformPict pictHandle = picture->GetPlatformPict();
  915.     FW_ASSERT(pictHandle != 0);
  916.  
  917.     // Just get picture color depth    at first
  918.     PictInfo pictInfo;
  919.     ::GetPictInfo(pictHandle, &pictInfo, 0, 0, 0, 0);
  920.  
  921.     // Now that we know the color depth, we are ready to get the color table
  922.     short nColors = pictInfo.depth > 8 ? 256 : 1 << pictInfo.depth;
  923.     ::GetPictInfo(pictHandle, &pictInfo, returnColorTable, nColors, systemMethod, 0);
  924.  
  925.     // Create a GWorld
  926.     FW_CPlatformRect gworldRect = pictPart;
  927.     ::OffsetRect(&gworldRect, -gworldRect.left, -gworldRect.top);
  928.     QDErr err = ::NewGWorld(&fPlatformBitmap, pictInfo.depth, &gworldRect,
  929.         pictInfo.theColorTable, NULL, useTempMem);
  930.     FW_ASSERT(err == noErr);
  931.     
  932.     ::DisposeCTable(pictInfo.theColorTable);
  933.  
  934.     FW_FailOnError(err);
  935.     if(fPlatformBitmap == NULL)
  936.     {
  937.         ::SetGWorld(curPort, gdh);
  938.         FW_Failure(FW_xGraphicException);
  939.     }
  940.     
  941.     // Copy the image
  942.     ::SetGWorld(fPlatformBitmap, NULL);
  943.     
  944.     FW_CPrivMacPixelLock lock(this);
  945. //    PixMapHandle pmh = lock.GetPixMapHandle();
  946.  
  947.     FW_CColor odfColor = fillColor;
  948.     RGBColor macColor(odfColor);
  949.     ::RGBBackColor(&macColor);
  950.     ::EraseRect(&gworldRect);
  951.  
  952.  
  953.     FW_PrivMacSetStdColors();
  954.     ::PenNormal();
  955.     FW_CPlatformRect rectPicture = pictInfo.sourceRect;
  956.     ::OffsetRect(&rectPicture, - FW_FixedToInt(pictPart.left), - FW_FixedToInt(pictPart.top));
  957.     ::DrawPicture(pictHandle, &rectPicture);
  958.  
  959.     ::SetGWorld(curPort, gdh);
  960.     
  961.     FW_END_CONSTRUCTOR
  962. }
  963. #endif
  964.  
  965. #ifdef FW_BUILD_MAC
  966. //----------------------------------------------------------------------------------------
  967. //    FW_CPrivBitmapRep::MacGetAsPicture
  968. //----------------------------------------------------------------------------------------
  969.  
  970. FW_HPicture FW_CPrivBitmapRep::MacGetAsPicture(const FW_SRect& bounds) const
  971. {
  972.     CGrafPtr     curPort;
  973.     GDHandle     gdh;
  974.     ::GetGWorld(&curPort, &gdh);
  975.  
  976.     FW_CPrivMacPixelLock lock((FW_HBitmap)this);
  977.     PixMapHandle pixMap = lock.GetPixMapHandle();
  978.  
  979.     GDHandle gdevice = ::GetGWorldDevice(fPlatformBitmap);
  980.  
  981.     ::SetGWorld(fPlatformBitmap, gdevice);
  982.  
  983.     FW_CPlatformRect plfmSrcRect = bounds;
  984.     FW_CPlatformRect plfmDstRect = bounds;
  985.     ::OffsetRect(&plfmDstRect, -plfmDstRect.left, -plfmDstRect.top);
  986.  
  987.     OpenCPicParams openParams;
  988.     openParams.srcRect    = plfmDstRect;
  989.     openParams.hRes        =
  990.     openParams.vRes     = 0x00480000;
  991.     openParams.version    = -2;
  992.     openParams.reserved1 =
  993.     openParams.reserved2 = 0;
  994.  
  995.     PicHandle hPict = ::OpenCPicture(&openParams);
  996.     ::CopyBits((BitMap*)*pixMap, (BitMap*)*pixMap,  
  997.                 &plfmSrcRect, &plfmDstRect, 
  998.                 srcCopy, NULL);
  999.     ::ClosePicture();
  1000.  
  1001.     ::SetGWorld(curPort, gdh);
  1002.  
  1003.     return FW_NEW(FW_CPrivPictureRep, (hPict));
  1004. }
  1005.  
  1006. #endif
  1007.  
  1008. #ifdef FW_BUILD_MAC
  1009.  
  1010. //----------------------------------------------------------------------------------------
  1011. //    FW_CPrivBitmapRep::MacLockPixels
  1012. //----------------------------------------------------------------------------------------
  1013.  
  1014. PixMapHandle FW_CPrivBitmapRep::MacLockPixels()
  1015. {
  1016.     if (++ fLockCount == 1)
  1017.     {
  1018.         FW_ASSERT(fPixMapHandle == NULL);
  1019.         fPixMapHandle = ::GetGWorldPixMap(fPlatformBitmap);
  1020.         ::LockPixels(fPixMapHandle);
  1021.     }
  1022.  
  1023.     return fPixMapHandle;
  1024. }
  1025. #endif
  1026.  
  1027. #ifdef FW_BUILD_MAC
  1028.  
  1029. //----------------------------------------------------------------------------------------
  1030. //    FW_CPrivBitmapRep::MacUnlockPixels
  1031. //----------------------------------------------------------------------------------------
  1032.  
  1033. void FW_CPrivBitmapRep::MacUnlockPixels()
  1034. {
  1035.     FW_ASSERT(fPixMapHandle != NULL);
  1036.     FW_ASSERT(fLockCount != 0);
  1037.     
  1038.     if (-- fLockCount == 0)
  1039.     {
  1040.         ::UnlockPixels(fPixMapHandle);    
  1041.         fPixMapHandle = NULL;
  1042.     }
  1043. }
  1044. #endif
  1045.  
  1046. #ifdef FW_BUILD_MAC
  1047. //----------------------------------------------------------------------------------------
  1048. //    FW_CPrivBitmapRep::MacIsPixelsLocked
  1049. //----------------------------------------------------------------------------------------
  1050.  
  1051. FW_Boolean FW_CPrivBitmapRep::MacIsPixelsLocked() const
  1052. {
  1053.     return fLockCount != 0;
  1054. }
  1055. #endif
  1056.  
  1057. //----------------------------------------------------------------------------------------
  1058. //    FW_CPrivBitmapRep::PrivDisposeBitmap
  1059. //----------------------------------------------------------------------------------------
  1060.  
  1061. void FW_CPrivBitmapRep::PrivDisposeBitmap()
  1062. {
  1063.     if (fOwnBitmap && fPlatformBitmap != NULL)
  1064.     {
  1065. #ifdef FW_BUILD_MAC
  1066.         ::DisposeGWorld(fPlatformBitmap);
  1067. #endif
  1068. #ifdef FW_BUILD_WIN
  1069.         ::DeleteObject(fPlatformBitmap);
  1070.         
  1071.         if (fWinPalette != NULL)
  1072.         {
  1073.             ::DeleteObject(fWinPalette);
  1074.             fWinPalette = NULL;
  1075.         }
  1076. #endif
  1077.     }
  1078.  
  1079.     fPlatformBitmap = NULL;
  1080.     fOwnBitmap = FALSE;
  1081. }
  1082.  
  1083. //----------------------------------------------------------------------------------------
  1084. //    FW_CPrivBitmapRep::PrivMakeBitmap
  1085. //----------------------------------------------------------------------------------------
  1086.  
  1087. void FW_CPrivBitmapRep::PrivMakeBitmap(
  1088.         short width, short height,
  1089.         short pixelSize, FW_Palette palette)
  1090. {
  1091.     FW_PlatformBitmap bitmap = NULL;
  1092.     
  1093.     FW_ASSERT(height != 0);
  1094.     FW_ASSERT(width != 0);
  1095.     
  1096. #ifdef FW_BUILD_MAC
  1097.     FW_CPlatformRect boundsRect(0, 0, width, height);
  1098.  
  1099.     OSErr err = ::NewGWorld(&bitmap, pixelSize, &boundsRect, palette, NULL, useTempMem);
  1100.     FW_FailOnError(err);
  1101. #endif
  1102. #ifdef FW_BUILD_WIN
  1103.     // Determine color depth for the DDB
  1104.     short bmPlanes = 1, bmBitsPixel = 1;
  1105.     if(pixelSize != 1)
  1106.         FW_PrivWinGetDisplayColorInfo(bmPlanes, bmBitsPixel);
  1107.  
  1108.     // Create the bitmap    
  1109.     bitmap = ::CreateBitmap(width, height, bmPlanes, bmBitsPixel, NULL);
  1110.     if(bitmap == NULL)
  1111.         FW_Failure(FW_xMemoryExhausted);
  1112.  
  1113.     // Update the color depth
  1114.     if(pixelSize != 0)
  1115.         fUserColorDepth = pixelSize;
  1116.     else
  1117.         fUserColorDepth = FW_DDBGetColorDepth(bitmap);
  1118.         
  1119.     // Copy the palette if there is one
  1120.     if (palette != NULL)
  1121.         fWinPalette = FW_CopyPalette(palette);
  1122. #endif
  1123.  
  1124.     fPlatformBitmap    = bitmap;
  1125.     fOwnBitmap    = TRUE;
  1126. }
  1127.  
  1128. //----------------------------------------------------------------------------------------
  1129. //    FW_CPrivBitmapRep::PrivReadFromStream
  1130. //----------------------------------------------------------------------------------------
  1131.  
  1132. void FW_CPrivBitmapRep::PrivReadFromStream(FW_CReadableStream& stream, FW_Boolean bDIBFileHeader)
  1133. {
  1134. #ifdef FW_BUILD_WIN
  1135.     FW_WinDIB dib = FW_DIBLoadFromStream(stream, bDIBFileHeader);
  1136.     
  1137.     // Get the palette
  1138.     fWinPalette = FW_DIBGetPalette(dib);
  1139.  
  1140.     FW_TRY
  1141.     {
  1142.         fPlatformBitmap = FW_DIBConvertToBitmap(dib, fWinPalette);
  1143.     }
  1144.     FW_CATCH_BEGIN
  1145.     FW_CATCH_EVERYTHING()
  1146.     {
  1147.         FW_DIBFree(dib);
  1148.         FW_THROW_SAME();
  1149.     }
  1150.     FW_CATCH_END
  1151.     
  1152.     FW_DIBFree(dib);
  1153.  
  1154.     // Update the color depth
  1155.     fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
  1156. #endif
  1157.  
  1158. #ifdef FW_BUILD_MAC
  1159.     // Read the BITMAPFILEINFO header
  1160.     if(bDIBFileHeader)
  1161.     {
  1162.         BITMAPFILEHEADER bmfh;
  1163.         
  1164.         stream.Read((void*) &bmfh, sizeof(bmfh));
  1165.         
  1166.         MacRepackValue(&bmfh.bfType);
  1167.         MacRepackValue(&bmfh.bfSize);
  1168.         MacRepackValue(&bmfh.bfReserved1);
  1169.         MacRepackValue(&bmfh.bfReserved2);
  1170.         MacRepackValue(&bmfh.bfOffBits);
  1171.     
  1172.         if(bmfh.bfType != FW_kWinBitmapSignature || bmfh.bfReserved1 != 0 || bmfh.bfReserved2 != 0)        
  1173.             FW_Failure(FW_xInvalidBitmapData);
  1174.     }
  1175.  
  1176.     // Start reading the header
  1177.     FW_Boolean bIsWindowsBitmap;
  1178.     BITMAPINFOHEADER bmih;
  1179.  
  1180.     stream.Read((void*) &bmih.biSize, sizeof(bmih.biSize));
  1181.  
  1182.     MacRepackValue(&bmih.biSize);
  1183.  
  1184.     if(bmih.biSize == sizeof(BITMAPINFOHEADER))                // Windows bitmap
  1185.     {
  1186.         // Read the Windows header
  1187.         stream.Read((void*) &bmih.biWidth, sizeof(bmih) - sizeof(bmih.biSize));
  1188.         
  1189.         MacRepackValue(&bmih.biWidth);
  1190.         MacRepackValue(&bmih.biHeight);
  1191.         MacRepackValue(&bmih.biPlanes);
  1192.         MacRepackValue(&bmih.biBitCount);
  1193.         MacRepackValue(&bmih.biCompression);
  1194.         MacRepackValue(&bmih.biSizeImage);
  1195.         MacRepackValue(&bmih.biXPelsPerMeter);
  1196.         MacRepackValue(&bmih.biYPelsPerMeter);
  1197.         MacRepackValue(&bmih.biClrUsed);
  1198.         MacRepackValue(&bmih.biClrImportant);
  1199.  
  1200.         bIsWindowsBitmap = TRUE;
  1201.     }
  1202.     else if(bmih.biSize == sizeof(BITMAPCOREHEADER))        // OS/2 bitmap
  1203.     {
  1204.         // Read the OS/2 header
  1205.         BITMAPCOREHEADER bmch;
  1206.         
  1207.         stream.Read((void* )&bmch.bcWidth, sizeof(bmch) - sizeof(bmch.bcSize));
  1208.  
  1209.         MacRepackValue(&bmch.bcWidth);
  1210.         MacRepackValue(&bmch.bcHeight);
  1211.         MacRepackValue(&bmch.bcPlanes);
  1212.         MacRepackValue(&bmch.bcBitCount);
  1213.  
  1214.         // Plug the data into the Windows header
  1215.         bmih.biWidth            =    bmch.bcWidth;
  1216.         bmih.biHeight            =    bmih.biHeight;
  1217.         bmih.biPlanes            =    bmch.bcPlanes;
  1218.         bmih.biBitCount            =    bmch.bcBitCount;
  1219.         bmih.biCompression        =    0;
  1220.         bmih.biSizeImage        =    0;
  1221.         bmih.biXPelsPerMeter    =    0;
  1222.         bmih.biYPelsPerMeter    =    0;
  1223.         bmih.biClrUsed            =    0;
  1224.         bmih.biClrImportant        =    0;
  1225.  
  1226.         bIsWindowsBitmap = FALSE;
  1227.     }
  1228.     else
  1229.         FW_Failure(FW_xInvalidBitmapData);
  1230.  
  1231.     // Check for compression flag -- we don't support it!
  1232.     if(bmih.biCompression != 0)
  1233.         FW_Failure(FW_xInvalidBitmapData);
  1234.  
  1235.     // Determine the size of the color table
  1236.     short bitDepth = bmih.biBitCount;
  1237.     short colorCount = bmih.biClrUsed != 0 ? bmih.biClrUsed : bitDepth >= 16 ? 0 : (1 << bitDepth);
  1238.  
  1239.     // Read the color table
  1240.     CTabHandle colorTabHandle = NULL;
  1241.     if(colorCount != 0)
  1242.     {
  1243.         Size colorTableSize = sizeof(ColorTable) + sizeof(ColorSpec) * (colorCount - 1);
  1244.         FW_CAcquireTemporarySystemHandle colorTableMemory(colorTableSize);
  1245.         CTabPtr colorTablePtr = (CTabPtr) colorTableMemory.GetPointer();
  1246.  
  1247.         for(int i = 0; i < colorCount; colorTablePtr->ctTable[i].value = i, ++i)
  1248.         {
  1249.             if(bIsWindowsBitmap)
  1250.             {
  1251.                 RGBQUAD quad;
  1252.                 stream.Read((void*) &quad, sizeof(quad));
  1253.                     
  1254.                 colorTablePtr->ctTable[i].rgb.red    = (quad.rgbRed        << 8) | quad.rgbRed;
  1255.                 colorTablePtr->ctTable[i].rgb.green    = (quad.rgbGreen    << 8) | quad.rgbGreen;
  1256.                 colorTablePtr->ctTable[i].rgb.blue    = (quad.rgbBlue        << 8) | quad.rgbBlue;
  1257.             }
  1258.             else
  1259.             {
  1260.                 RGBTRIPLE trip;
  1261.                 stream.Read((void*) &trip, sizeof(trip));
  1262.                     
  1263.                 colorTablePtr->ctTable[i].rgb.red    = trip.rgbtRed    << 8;
  1264.                 colorTablePtr->ctTable[i].rgb.green    = trip.rgbtGreen<< 8;
  1265.                 colorTablePtr->ctTable[i].rgb.blue    = trip.rgbtBlue    << 8;
  1266.             }
  1267.         }
  1268.  
  1269.         colorTablePtr->ctSeed    = 0;
  1270.         colorTablePtr->ctFlags    = 0;
  1271.         colorTablePtr->ctSize    = colorCount - 1;
  1272.  
  1273.         colorTabHandle = (CTabHandle) colorTableMemory.Orphan();
  1274.         
  1275.         ::CTabChanged(colorTabHandle);
  1276.     }
  1277.  
  1278.     // Create a GWorld
  1279.     FW_CPlatformRect bounds(0, 0, bmih.biWidth, bmih.biHeight);
  1280.     OSErr err = ::NewGWorld(&fPlatformBitmap, bitDepth, &bounds,
  1281.         colorTabHandle, NULL, useTempMem);
  1282.  
  1283.     if (colorTabHandle != NULL)
  1284.         ::DisposeCTable(colorTabHandle);
  1285.  
  1286.     FW_FailOnError(err);
  1287.  
  1288.     // Lock the memory pixmap
  1289.     FW_CPrivMacPixelLock lock(this);
  1290.     PixMapHandle memPixMap = lock.GetPixMapHandle();
  1291.     void* memBaseAddr = ::GetPixBaseAddr(memPixMap);
  1292.  
  1293.     // Read the bits
  1294.     short resRowBytes = ((bmih.biWidth * bitDepth + 31) & ~31) / 8;
  1295.     short memRowBytes = (*memPixMap)->rowBytes & 0x7FFF;
  1296.     FW_ASSERT(resRowBytes <= memRowBytes);
  1297.  
  1298.     char* curBuffer    = (char*) memBaseAddr + (bmih.biHeight - 1) * memRowBytes;
  1299.     
  1300.     for(int row = bmih.biHeight - 1; row >= 0; -- row, curBuffer -= memRowBytes)
  1301.     {
  1302.         // Read and repack the next row
  1303.         stream.Read(curBuffer, resRowBytes);
  1304.         MacRepackResourceRow(curBuffer, bitDepth, resRowBytes);
  1305.     }
  1306. #endif
  1307. }
  1308.  
  1309. #ifdef FW_BUILD_MAC
  1310.  
  1311. //========================================================================================
  1312. // CLASS FW_CPrivMacPixelLock
  1313. //========================================================================================
  1314.  
  1315. FW_DEFINE_AUTO(FW_CPrivMacPixelLock)
  1316.  
  1317. //----------------------------------------------------------------------------------------
  1318. // FW_CPrivMacPixelLock::FW_CPrivMacPixelLock
  1319. //----------------------------------------------------------------------------------------
  1320.  
  1321. FW_CPrivMacPixelLock::FW_CPrivMacPixelLock(FW_HBitmap rep) :
  1322.     fBitmap(rep)
  1323. {
  1324.     fPixMapHandle = FW_PrivBitmap_MacLockPixels(fBitmap);
  1325.  
  1326.     FW_END_CONSTRUCTOR
  1327. }
  1328.  
  1329. //----------------------------------------------------------------------------------------
  1330. // FW_CPrivMacPixelLock::~FW_CPrivMacPixelLock
  1331. //----------------------------------------------------------------------------------------
  1332.  
  1333. FW_CPrivMacPixelLock::~FW_CPrivMacPixelLock()
  1334. {
  1335.     FW_START_DESTRUCTOR
  1336.  
  1337.     FW_PrivBitmap_MacUnlockPixels(fBitmap);
  1338. }
  1339.  
  1340. //----------------------------------------------------------------------------------------
  1341. // FW_CPrivMacPixelLock::GetPixMapHandle
  1342. //----------------------------------------------------------------------------------------
  1343.  
  1344. PixMapHandle FW_CPrivMacPixelLock::GetPixMapHandle() const
  1345. {
  1346.     return fPixMapHandle;
  1347. }
  1348.  
  1349. #endif
  1350.