OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
celarray.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1993, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of a bitmap Cel array class.
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9#include <owl/celarray.h>
10
11#include <algorithm>
12
13namespace owl {
14
16DIAG_DECLARE_GROUP(OwlGadget); // Common Controls diagnostic group
17
18bool OwlCopyBmp(TBitmap& dstBM, const TBitmap& srcBM, const TPoint& pt,
19 const TSize& size,const TPoint offset=TPoint(0,0));
20
21//
22/// Constructs a TCelArray from a bitmap by slicing the bitmap into a horizontal
23/// array of cels of a specified size. If autoDelete is true, TCelArray can
24/// automatically delete the bitmap. The ShouldDelete data member defaults to true,
25/// ensuring that the handle will be deleted when the bitmap is destroyed. If
26/// numRows is 0, the number of rows is calculated using the bitmap height and the
27/// celSize y parameter.
28//
31{
33
34 NGrowBy = 1;
35 NCels = NCelsUsed = std::max(1, numCels);
36 NRows = std::max(1, numRows);
37 CSize = celSize.cx && celSize.cy ?
38 celSize :
39 TSize(bmp->Width() / NCels, bmp->Height() / NRows);
40 Offs = offset;
41 NCurRow = 0;
42 ShouldDelete = ToBool(autoDelete == AutoDelete);
43
44 Bitmap = bmp;
45
46 TRACEX(OwlGadget, OWL_CDLEVEL, "TCelArray constructed @" << (void*)this <<
47 " from slicing the bitmap @" << (void*)bmp);
48}
49
50//
51/// Constructs a TCelArray from a device independent bitmap (DIB) by slicing the DIB
52/// into a horizontal array of evenly sized cels. If numRows is 0, the number of
53/// rows is calculated using the bitmap height and the celSize y parameter.
54//
56{
57 NGrowBy = 1;
58 NCels = NCelsUsed = std::max(1, numCels);
59 NRows = std::max(1, numRows);
60 CSize = TSize(dib.Width() / NCels, dib.Height() / NRows);
61 NCurRow = 0;
62 Offs = TPoint(0, 0);
63 ShouldDelete = true;
64
66 Bitmap = new TBitmap(dib, &palette);
67
68 TRACEX(OwlGadget, OWL_CDLEVEL, "TCelArray constructed @" << (void*)this <<
69 " from slicing the dib @" << (void*)&dib);
70}
71
72//
73/// Constructs a TCelArray as a copy of an existing one. If the original TCelArray
74/// owned its bitmap, the constructor copies this bitmap; otherwise, it keeps a
75/// reference to the bitmap.
76//
78{
79 Offs = src.Offs;
80 CSize = src.CSize;
81 NCels = src.NCels;
82 NCelsUsed = src.NCelsUsed;
83 NGrowBy = src.NGrowBy;
84 BkColor = src.BkColor;
85 NCurRow = src.NCurRow;
86 NRows = src.NRows;
87
88 ShouldDelete = src.ShouldDelete;
89
90 Bitmap = ShouldDelete ? new TBitmap(*src.Bitmap) : src.Bitmap;
91
92 TRACEX(OwlGadget, OWL_CDLEVEL, "Copied constructed TCelArray @" << (void*)this <<
93 " from @" << (void*)&src);
94}
95
96//
97/// Constructs an empty CelArray of a given size. flags is not used.
98//
99TCelArray::TCelArray(const TSize& size, uint /*flags*/, int initCount, int growBy, int numRows)
100{
101 // Init variables
102 //
103 Offs = TPoint(0, 0);
104 CSize = size;
105 NCels = initCount > 1 ? initCount : 1;
106 NGrowBy = growBy;
107 NCurRow = 0;
108 NRows = std::max(1, numRows);
109 ShouldDelete = true;
110 Bitmap = nullptr;
111
112 // Allocate bitmap(s)
113 //
114 Resize(NCels);
115
116 // Update count of Cels
117 //
118 NCelsUsed = 0;
119
120 TRACEX(OwlGadget, OWL_CDLEVEL, "Empty TCelArray constructed @" << (void*)this <<
121 " size (" << size.cx << "x" << size.cy << ")");
122}
123
124//
125/// Destruct the CelArray and clean up its resources
126//
127/// If ShouldDelete is true (the default value), the bitmap is deleted. If
128/// ShouldDelete is false, no action is taken.
129//
131{
132 if (ShouldDelete)
133 delete Bitmap;
134
135 TRACEX(OwlGadget, OWL_CDLEVEL, "TCelArray destructed @" << (void*)this);
136}
137
138//
139/// Assign a CelArray over this CelArray, replacing all contents
140//
143{
144 if (ShouldDelete)
145 delete Bitmap;
146
147 ShouldDelete = src.ShouldDelete;
148 Bitmap = ShouldDelete ? new TBitmap(*src.Bitmap) : src.Bitmap;
149
150 NCels = src.NCels;
151 CSize = src.CSize;
152 NCurRow = src.NCurRow;
153 NRows = src.NRows;
154 Offs = src.Offs;
155
156 TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this <<
157 " contents copied over with TCelArray @" << (void*)&src);
158 return *this;
159}
160
161//
162/// Return the offset of a given cel in the CelArray's bitmap
163//
164TPoint
165TCelArray::CelOffset(int cel, int row) const
166{
167 row = row < 0 ? NCurRow : row;
168 return TPoint(Offs.x+cel*CSize.cx, Offs.y+CSize.cy*row);
169}
170
171//
172/// Return the bounding rect of a given cel in the CelArray's bitmap
173//
174TRect
175TCelArray::CelRect(int cel, int row) const
176{
177 row = row < 0 ? NCurRow : row;
178 return TRect(TPoint(Offs.x+cel*CSize.cx, Offs.y+CSize.cy*row), CSize);
179}
180
181//
182/// Add new cel(s) to the CelArray - return index of new addition.
183/// No mask bitmap is added.
184//
185int
187{
188 int width = image.Width();
189 int count = width / CelSize().cx;
190
191 if (!MaybeResize(count))
192 return -1;
193
194 OwlCopyBmp(*Bitmap, image, CelOffset(NCelsUsed,0), image.Size());
195
196 int index = NCelsUsed;
197 NCelsUsed += count;
198
199 TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " added bitmap @" <<
200 (void*)&image);
201
202 return index;
203}
204
205//
206/// Add a cel from another CelArray to this CelArray
207//
208int
209TCelArray::Add(const TCelArray& src, int index)
210{
211// if (src.CSize != CSize)
212// return -1;
213
214 if (NCelsUsed >= NCels)
215 if (!Resize(NCels + NGrowBy))
216 return -1;
217
218 OwlCopyBmp(*Bitmap, static_cast<const TBitmap&>(src), CelOffset(NCelsUsed,0),
219 TSize(CSize.cx,CSize.cy*NRows),CelRect(index,0).TopLeft());
220
221 TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " added TCelArray @" <<
222 (void*)&src << " index 0x" << index);
223
224 return NCelsUsed++;
225}
226
227//
228/// Removes a cel from this CelArray. If index is < 0, all cels are removed. Returns
229/// true if cels are removed; false otherwise.
230//
231bool
233{
234 if (index >= NCelsUsed)
235 return false;
236
237 if (index < 0) {
238 NCelsUsed = 0; // Remove all
239 }
240 else if (index < NCelsUsed) {
241 if (index < NCelsUsed-1) {
242 TPoint offs(CelOffset(index,0));
243 TMemoryDC bitmapDC(*Bitmap);
244 bitmapDC.BitBlt(offs.x, offs.y, (NCelsUsed-index-1)*CSize.cx,
245 CSize.cy*NRows,bitmapDC, offs.x+CSize.cx, offs.y);
246 }
247 NCelsUsed--;
248 }
249
250 TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " removed index 0x" << index);
251 return true;
252}
253
254//
255/// Replace a cel in this CelArray.
256// !CQ can it handle >1 cel?
257//
258bool
260{
261 if (index >= 0 && index < NCelsUsed) {
262 OwlCopyBmp(*Bitmap, image, CelOffset(index,0), TSize(CSize.cx,CSize.cy*NRows));
263 TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " index 0x" << index <<
264 " replaced by TBitmap @" << (void*)&image);
265 return true;
266 }
267 return false;
268}
269
270//
271/// Replaces a cel in this CelArray, from another CelArray.
272//
273bool
274TCelArray::Replace(int index, const TCelArray& src, int srcidx)
275{
276 if (index >= 0 && index < NCelsUsed) {
277 OwlCopyBmp(*Bitmap, static_cast<const TBitmap&>(src), CelOffset(index,0),
278 TSize(CSize.cx,CSize.cy*NRows), CelRect(srcidx,0).TopLeft());
279 TRACEX(OwlGadget, 1, "TCelArray @" << (void*)this << " index 0x" << index <<
280 " replaced by TCelArray @" << " index 0x" << srcidx);
281 return true;
282 }
283 return false;
284}
285
286//
287/// Draws the cel at index onto the DC at position x and y.
288//
289bool
290TCelArray::BitBlt(int index, TDC& dstDC, int x, int y, uint32 rop)
291{
292 TMemoryDC srcDC(*Bitmap);
293 TRect cr = CelRect(index,-1);
294 dstDC.BitBlt(x, y, cr.Width(), cr.Height(), srcDC, cr.left, cr.top, rop);
295 return true;
296}
297
298//
299/// Draws the image of the cel onto the DC.
300//
301bool
302TCelArray::BitBlt(int index, TDC& dstDC, int x, int y, int /*dx*/, int /*dy*/,
303 const TColor& /*bgClr*/, const TColor& /*fgClr*/)
304{
305 TMemoryDC srcDC(*Bitmap);
306 TRect cr = CelRect(index,-1);
307 dstDC.BitBlt(x, y, cr.Width(), cr.Height(), srcDC, cr.left, cr.top);
308 return true;
309}
310
311//
312/// Draws the image of the cel onto the DC.
313//
314bool
316{
317 TMemoryDC srcDC(*Bitmap);
318 TRect cr = CelRect(index,-1);
319 dstDC.StretchBlt(dstRect.left,dstRect.top, dstRect.Width(),dstRect.Height(),
320 srcDC, cr.left, cr.top, cr.Width(), cr.Height(), rop);
321 return true;
322}
323
324//------------------------------------------------------------------------
325// Helper routines
326//
327
328//
329/// Copy specified bitmap to the destination DC
330//
331bool
332OwlCopyBmp(TBitmap& dstBM, const TBitmap& srcBM, const TPoint& pt, const TSize& size, const TPoint offset)
333{
336 return dstDC.BitBlt(TRect(pt, size), srcDC, offset);
337}
338
339//
340/// Resize CelArray as needed to accomodate 'need' more cels. Return false on
341/// failure.
342//
343bool
344TCelArray::MaybeResize(int need)
345{
346 if (NCelsUsed + need > NCels)
347 if (!Resize(NCels + NGrowBy*((NCelsUsed+need-NCels) / NGrowBy + 1)))
348 return false;
349 return true;
350}
351
352//
353/// Resize the CelArray by re-allocating the bitmap(s) to the new size and copying
354/// over.
355//
356bool
357TCelArray::Resize(int newCount)
358{
359 // Can't resize--the bitmap is not ours
360 //
361 if (!ShouldDelete)
362 return false;
363
364 TBitmap* bitmap = new TBitmap(TScreenDC(), CSize.cx*newCount, CSize.cy*NRows);
365
366 // Copy old bitmap if there is one
367 //
368 if (Bitmap) {
369 TMemoryDC srcDC(*Bitmap);
370 TMemoryDC dstDC(*bitmap);
371 dstDC.BitBlt(TRect(0, 0, CSize.cx*NCels, CSize.cy*NRows), srcDC, TPoint(0));
372
373 // Cleanup old bitmap
374 //
375 srcDC.RestoreBitmap();
376 delete Bitmap;
377 }
378
379 // Update bitmap data member
380 //
381 Bitmap = bitmap;
382
383 // Update total number of Cels
384 //
385 NCels = newCount;
386 return true;
387}
388
389} // OWL namespace
390//==============================================================================
391
Definition of a bitmap Cel array class.
#define PRECONDITION(condition)
Definition checks.h:227
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define TRACEX(group, level, message)
Definition checks.h:263
TBitmap is the GDI bitmap class derived from TGdiObject.
Definition gdiobjec.h:510
TCelArray is a horizontal array of cels (a unit of animation) created by slicing a portion of or an e...
Definition celarray.h:35
TSize CelSize() const
Return the size of the celarray.
Definition celarray.h:133
bool StretchBlt(int index, TDC &dc, const TRect &dstRect, uint32 rop=SRCCOPY)
Draws the image of the cel onto the DC.
Definition celarray.cpp:315
TCelArray(TBitmap *bmp, int numCels, TSize celSize=TSize(), TPoint offset=TPoint(), int numRows=1, TAutoDelete=AutoDelete)
Constructs a TCelArray from a bitmap by slicing the bitmap into a horizontal array of cels of a speci...
Definition celarray.cpp:29
bool BitBlt(int index, TDC &dc, int x, int y, uint32 rop=SRCCOPY)
Draws the cel at index onto the DC at position x and y.
Definition celarray.cpp:290
bool Remove(int index=-1)
Removes a cel from this CelArray.
Definition celarray.cpp:232
TCelArray & operator=(const TCelArray &)
Assign a CelArray over this CelArray, replacing all contents.
Definition celarray.cpp:142
virtual ~TCelArray()
Destruct the CelArray and clean up its resources.
Definition celarray.cpp:130
bool Replace(int index, const TBitmap &image)
Replace a cel in this CelArray.
Definition celarray.cpp:259
int Add(const TBitmap &image)
Add new cel(s) to the CelArray - return index of new addition.
Definition celarray.cpp:186
TPoint CelOffset(int cel) const
Returns the position of the upper left corner of a given cel from the current row,...
Definition celarray.h:141
TRect CelRect(int cel) const
Returns the upper left and lower right corner of a given cell from the current row,...
Definition celarray.h:149
Class wrapper for management of color values.
Definition color.h:245
TDC is the root class for GDI DC wrappers.
Definition dc.h:64
Pseudo-GDI object Device Independent Bitmap (DIB) class.
Definition gdiobjec.h:795
A device context (DC) class derived from TCreatedDC, TMemoryDC provides access to a memory DC.
Definition dc.h:784
TPalette is the GDI Palette class derived from TGdiObject.
Definition gdiobjec.h:413
TPoint is a support class, derived from tagPOINT.
Definition geometry.h:87
TRect is a mathematical class derived from tagRect.
Definition geometry.h:308
The tagSIZE struct is defined as.
Definition geometry.h:234
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition gdibase.h:70
@ AutoDelete
Definition gdibase.h:70
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
unsigned long uint32
Definition number.h:34
bool ToBool(const T &t)
Definition defs.h:291
OWL_DIAGINFO
Definition animctrl.cpp:14
unsigned int uint
Definition number.h:25
bool OwlCopyBmp(TBitmap &dstBM, const TBitmap &srcBM, const TPoint &pt, const TSize &size, const TPoint offset=TPoint(0, 0))
Copy specified bitmap to the destination DC.
Definition celarray.cpp:332
#define OWL_CDLEVEL
Definition defs.h:171
#define CONST_CAST(targetType, object)
Definition defs.h:273