2 * Copyright 2006, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Stephan Aßmus <superstippi@gmx.de>
23 Canvas::Canvas(BRect frame
)
37 Canvas::IsValid() const
39 return fBounds
.IsValid();
46 int32 count
= CountLayers();
47 for (int32 i
= 0; i
< count
; i
++)
48 delete LayerAtFast(i
);
54 Canvas::AddLayer(Layer
* layer
)
56 return AddLayer(layer
, CountLayers());
61 Canvas::AddLayer(Layer
* layer
, int32 index
)
63 return layer
&& AddItem((void*)layer
, index
);
68 Canvas::RemoveLayer(int32 index
)
70 return (Layer
*)RemoveItem(index
);
75 Canvas::RemoveLayer(Layer
* layer
)
77 return RemoveItem((void*)layer
);
82 Canvas::LayerAt(int32 index
) const
84 return (Layer
*)ItemAt(index
);
89 Canvas::LayerAtFast(int32 index
) const
91 return (Layer
*)ItemAtFast(index
);
96 Canvas::IndexOf(Layer
* layer
) const
98 return BList::IndexOf((void*)layer
);
103 Canvas::CountLayers() const
110 Canvas::HasLayer(Layer
* layer
) const
112 return HasItem((void*)layer
);
117 Canvas::SetBounds(BRect bounds
)
119 if (bounds
.IsValid())
125 Canvas::Bounds() const
132 Canvas::Compose(BBitmap
* into
, BRect area
) const
134 if (into
&& into
->IsValid()
135 && area
.IsValid() && area
.Intersects(into
->Bounds())) {
136 area
= area
& into
->Bounds();
137 int32 count
= CountLayers();
138 for (int32 i
= count
- 1; Layer
* layer
= LayerAt(i
); i
--) {
139 layer
->Compose(into
, area
);
146 Canvas::Bitmap() const
148 BBitmap
* bitmap
= new BBitmap(fBounds
, 0, B_RGBA32
);
149 if (!bitmap
->IsValid()) {
154 // this bitmap is uninitialized, clear to black/fully transparent
155 memset(bitmap
->Bits(), 0, bitmap
->BitsLength());
156 Compose(bitmap
, fBounds
);
157 // remove image data where alpha = 0 to improve compression later on
158 uint8
* bits
= (uint8
*)bitmap
->Bits();
159 uint32 bpr
= bitmap
->BytesPerRow();
160 uint32 width
= bitmap
->Bounds().IntegerWidth() + 1;
161 uint32 height
= bitmap
->Bounds().IntegerHeight() + 1;
163 uint8
* bitsHandle
= bits
;
164 for (uint32 x
= 0; x
< width
; x
++) {
165 if (!bitsHandle
[3]) {
181 static const char* LAYER_KEY
= "layer";
182 static const char* BOUNDS_KEY
= "bounds";
186 Canvas::Unarchive(const BMessage
* archive
)
193 if (archive
->FindRect(BOUNDS_KEY
, &bounds
) < B_OK
)
197 // restore each layer
198 BMessage layerMessage
;
200 archive
->FindMessage(LAYER_KEY
, i
, &layerMessage
) == B_OK
;
203 Layer
* layer
= new (nothrow
) Layer();
204 if (!layer
|| layer
->Unarchive(&layerMessage
) < B_OK
205 || !AddLayer(layer
)) {