home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / OWLSRC.PAK / CELARRAY.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  8.1 KB  |  338 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1993, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.12  $
  6. //
  7. // Implementation of a bitmap Cel array class.
  8. //----------------------------------------------------------------------------
  9. #include <owl/pch.h>
  10. #if !defined(OWL_CELARRAY_H)
  11. # include <owl/celarray.h>
  12. #endif
  13.  
  14. OWL_DIAGINFO;
  15. DIAG_DECLARE_GROUP(OwlGadget);    // Common Controls diagnostic group
  16.  
  17. bool OwlCopyBmp(TBitmap& dstBM, const TBitmap& srcBM, const TPoint& pt, const TSize& size);
  18.  
  19. //
  20. // Construct a TCelArray from a bitmap, slicing a portion of the bitmap up
  21. // into a horizontal array of specified sized cels.
  22. // The CelArray can own (& delete) the bitmap or not, determined by autoDelete
  23. //
  24. TCelArray::TCelArray(TBitmap* bmp, int numCels, TSize celSize,
  25.                      TPoint offset, TAutoDelete autoDelete)
  26. {
  27.   PRECONDITION(bmp);
  28.  
  29.   NGrowBy = 1;
  30.   NCels = NCelsUsed = numCels < 1 ? 1 : numCels;
  31.   CSize = celSize.cx && celSize.cy ?
  32.             celSize :
  33.             TSize(bmp->Width() / NCels, bmp->Height());
  34.   Offs = offset;
  35.   ShouldDelete = ToBool(autoDelete == AutoDelete);
  36.  
  37.   Bitmap = bmp;
  38.  
  39.   TRACEX(OwlGadget, OWL_CDLEVEL, "TCelArray constructed @" << (void*)this <<
  40.     " from slicing the bitmap @" << (void*)bmp);
  41. }
  42.  
  43. //
  44. // Construct a TCelArray from a dib, slicing the dib up into a horizontal array
  45. // of even sized cels
  46. //
  47. TCelArray::TCelArray(const TDib& dib, int numCels)
  48. {
  49.   NGrowBy = 1;
  50.   NCels = NCelsUsed = numCels < 1 ? 1 : numCels;
  51.   CSize = TSize(dib.Width() / NCels, dib.Height());
  52.   Offs = 0;
  53.   ShouldDelete = true;
  54.  
  55.   Bitmap = new TBitmap(dib, &TPalette((HPALETTE)::GetStockObject(DEFAULT_PALETTE)));
  56.  
  57.   TRACEX(OwlGadget, OWL_CDLEVEL, "TCelArray constructed @" << (void*)this <<
  58.     " from slicing the dib @" << (void*)&dib);
  59. }
  60.  
  61. //
  62. // Construct a TCelArray as a copy of an existing one. Copy Bitmap iff
  63. // original owned its Bitmap, else just keep a ref to it also.
  64. //
  65. TCelArray::TCelArray(const TCelArray& src)
  66. {
  67.   Offs = src.Offs;
  68.   CSize =  src.CSize;
  69.   NCels = src.NCels;
  70.   NCelsUsed = src.NCelsUsed;
  71.   NGrowBy = src.NGrowBy;
  72.   BkColor = src.BkColor;
  73.  
  74.   ShouldDelete = src.ShouldDelete;
  75.  
  76.   Bitmap = ShouldDelete ? new TBitmap(*src.Bitmap) : src.Bitmap;
  77.  
  78.   TRACEX(OwlGadget, OWL_CDLEVEL, "Copied constructed TCelArray @" << (void*)this <<
  79.     " from @" << (void*)&src);
  80. }
  81.  
  82. //
  83. // Construct an empty CelArray of a given size
  84. //
  85. TCelArray::TCelArray(const TSize& size, uint /*flags*/, int initCount, int growBy)
  86. {
  87.   // Init variables
  88.   //
  89.   Offs     = 0;
  90.   CSize    = size;
  91.   NCels    = initCount > 1 ? initCount : 1;
  92.   NGrowBy  = growBy;
  93.   ShouldDelete = true;
  94.   Bitmap   = 0;
  95.  
  96.   // Allocate bitmap(s)
  97.   //
  98.   Resize(NCels);
  99.  
  100.   // Update count of Cels
  101.   //
  102.   NCelsUsed = 0;
  103.  
  104.   TRACEX(OwlGadget, OWL_CDLEVEL, "Empty TCelArray constructed @" << (void*)this <<
  105.     " size (" << size.cx << "x" << size.cy << ")");
  106. }
  107.  
  108. //
  109. // Destruct the CelArray and clean up its resources
  110. //
  111. TCelArray::~TCelArray()
  112. {
  113.   if (ShouldDelete)
  114.     delete Bitmap;
  115.  
  116.   TRACEX(OwlGadget, OWL_CDLEVEL, "TCelArray destructed @" << (void*)this);
  117. }
  118.  
  119. //
  120. // Assign a CelArray over this CelArray, replacing all contents
  121. //
  122. TCelArray&
  123. TCelArray::operator =(const TCelArray& src)
  124. {
  125.   if (ShouldDelete)
  126.     delete Bitmap;
  127.  
  128.   ShouldDelete = src.ShouldDelete;
  129.   Bitmap = ShouldDelete ? new TBitmap(*src.Bitmap) : src.Bitmap;
  130.  
  131.   NCels = src.NCels;
  132.   CSize =  src.CSize;
  133.   Offs = src.Offs;
  134.  
  135.   TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this <<
  136.     " contents copied over with TCelArray @" << (void*)&src);
  137.   return *this;
  138. }
  139.  
  140. //
  141. // Return the offset of a given cel in the CelArray's bitmap
  142. //
  143. TPoint
  144. TCelArray::CelOffset(int cel) const
  145. {
  146.   return TPoint(Offs.x+cel*CSize.cx, Offs.y);
  147. }
  148.  
  149. //
  150. // Return the bounding rect of a given cel in the CelArray's bitmap
  151. //
  152. TRect
  153. TCelArray::CelRect(int cel) const
  154. {
  155.   return TRect(TPoint(Offs.x+cel*CSize.cx, Offs.y), CSize);
  156. }
  157.  
  158. //
  159. // Add new cel(s) to the CelArray - return index of new addition.
  160. // No mask bitmap is added.
  161. //
  162. int
  163. TCelArray::Add(const TBitmap& image)
  164. {
  165.   int width = image.Width();
  166.   int count = width / CelSize().cx;
  167.  
  168.   if (!MaybeResize(count))
  169.     return -1;
  170.  
  171.   OwlCopyBmp(*Bitmap, image, CelOffset(NCelsUsed), image.Size());
  172.  
  173.   int index = NCelsUsed;
  174.   NCelsUsed += count;
  175.  
  176.   TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " added bitmap @" <<
  177.     (void*)&image);
  178.  
  179.   return index;
  180. }
  181.  
  182. //
  183. // Add a cel from another CelArray to this CelArray
  184. //
  185. #if defined(__TRACE)
  186. int
  187. TCelArray::Add(const TCelArray& src, int index)
  188. #else
  189. int
  190. TCelArray::Add(const TCelArray& src, int)
  191. #endif
  192. {
  193. //  if (src.CSize != CSize)
  194. //    return -1;
  195.  
  196.   if (NCelsUsed >= NCels)
  197.     if (!Resize(NCels + NGrowBy))
  198.       return -1;
  199.  
  200.   OwlCopyBmp(*Bitmap, (const TBitmap&)src, CelOffset(NCelsUsed), CelSize());
  201.  
  202.   TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " added TCelArray @" <<
  203.     (void*)&src << " index 0x" << index);
  204.  
  205.   return NCelsUsed++;
  206. }
  207.  
  208. //
  209. // Remove a cel from this CelArray.
  210. //
  211. bool
  212. TCelArray::Remove(int index)
  213. {
  214.   if (index >= NCelsUsed)
  215.     return false;
  216.  
  217.   if (index < 0) {
  218.     NCelsUsed = 0;  // Remove all
  219.   }
  220.   else if (index < NCelsUsed) {
  221.     if (index < NCelsUsed-1) {
  222.       TPoint offs(CelOffset(index));
  223.       TMemoryDC bitmapDC(*Bitmap);
  224.       bitmapDC.BitBlt(offs.x, offs.y, (NCelsUsed-index-1)*CSize.cx, CSize.cy,
  225.                       bitmapDC, offs.x+CSize.cx, offs.y);
  226.     }
  227.     NCelsUsed--;
  228.   }
  229.  
  230.   TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " removed index 0x" << index);
  231.   return true;
  232. }
  233.  
  234. //
  235. // Replace a cel in this CelArray.
  236. //
  237. bool
  238. TCelArray::Replace(int index, const TBitmap& image)
  239. {
  240.   if (index >= 0 && index < NCelsUsed) {
  241.     OwlCopyBmp(*Bitmap, image, CelOffset(index), CelSize());
  242.     TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " index 0x" << index <<
  243.       " replaced by TBitmap @" << (void*)&image);
  244.     return true;
  245.   }
  246.   return false;
  247. }
  248.  
  249. //
  250. // Draws the cel at index onto the DC at position x and y.
  251. //
  252. bool
  253. TCelArray::BitBlt(int index, TDC& dstDC, int x, int y)
  254. {
  255.   TMemoryDC srcDC(*Bitmap);
  256.   TRect cr = CelRect(index);
  257.   dstDC.BitBlt(x, y, cr.Width(), cr.Height(), srcDC, cr.left, cr.top);
  258.   return true;
  259. }
  260.  
  261. //
  262. // Draws the image of the cel onto the DC.
  263. //
  264. bool
  265. TCelArray::BitBlt(int index, TDC& dstDC, int x, int y, int /*dx*/, int /*dy*/,
  266.                   const TColor& /*bgClr*/, const TColor& /*fgClr*/)
  267. {
  268.   TMemoryDC srcDC(*Bitmap);
  269.   TRect cr = CelRect(index);
  270.   dstDC.BitBlt(x, y, cr.Width(), cr.Height(), srcDC, cr.left, cr.top);
  271.   return true;
  272. }
  273.  
  274. //------------------------------------------------------------------------
  275. // Helper routines 
  276. //
  277.  
  278. //
  279. // Copy specified bitmap to the destination DC
  280. //
  281. bool
  282. OwlCopyBmp(TBitmap& dstBM, const TBitmap& srcBM, const TPoint& pt, const TSize& size)
  283. {
  284.   TMemoryDC srcDC(CONST_CAST(TBitmap&, srcBM));
  285.   TMemoryDC dstDC(dstBM);
  286.   return dstDC.BitBlt(TRect(pt, size), srcDC, TPoint(0));
  287. }
  288.  
  289. //
  290. // Resize CelArray as needed to accomodate 'need' more cels. Return false on
  291. // failure.
  292. //
  293. bool
  294. TCelArray::MaybeResize(int need)
  295. {
  296.   if (NCelsUsed + need > NCels)
  297.     if (!Resize(NCels + NGrowBy*((NCelsUsed+need-NCels) / NGrowBy + 1)))
  298.       return false;
  299.   return true;
  300. }
  301.  
  302. //
  303. // Resize the CelArray by re-allocating the bitmap(s) to the new size &
  304. // copying over.
  305. //
  306. bool
  307. TCelArray::Resize(int newCount)
  308. {
  309.   // Can't resize--the bitmap is not ours
  310.   //
  311.   if (!ShouldDelete)
  312.     return false;
  313.  
  314.   TBitmap* bitmap = new TBitmap(TScreenDC(), CSize.cx*newCount, CSize.cy);
  315.  
  316.   // Copy old bitmap if there is one
  317.   //
  318.   if (Bitmap) {
  319.     TMemoryDC srcDC(*Bitmap);
  320.     TMemoryDC dstDC(*bitmap);
  321.     dstDC.BitBlt(TRect(0, 0, CSize.cx*NCels, CSize.cy), srcDC, TPoint(0));
  322.  
  323.     // Cleanup old bitmap
  324.     //
  325.     srcDC.RestoreBitmap();
  326.     delete Bitmap;
  327.   }
  328.  
  329.   // Update bitmap data member
  330.   //
  331.   Bitmap = bitmap;
  332.  
  333.   // Update total number of Cels
  334.   //
  335.   NCels = newCount;
  336.   return true;
  337. }
  338.