BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / translators / wonderbrush / Canvas.cpp
blob95c895fb2f23ca5a59d088ae3d37de1824e8c315
1 /*
2 * Copyright 2006, Haiku. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 */
9 #include "Canvas.h"
11 #include <new>
12 #include <stdio.h>
14 #include <Bitmap.h>
15 #include <Entry.h>
16 #include <Message.h>
18 #include "Layer.h"
20 using std::nothrow;
22 // constructor
23 Canvas::Canvas(BRect frame)
24 : BList(10),
25 fBounds(frame)
29 // destructor
30 Canvas::~Canvas()
32 MakeEmpty();
35 // IsValid
36 bool
37 Canvas::IsValid() const
39 return fBounds.IsValid();
42 // MakeEmpty
43 void
44 Canvas::MakeEmpty()
46 int32 count = CountLayers();
47 for (int32 i = 0; i < count; i++)
48 delete LayerAtFast(i);
49 BList::MakeEmpty();
52 // AddLayer
53 bool
54 Canvas::AddLayer(Layer* layer)
56 return AddLayer(layer, CountLayers());
59 // AddLayer
60 bool
61 Canvas::AddLayer(Layer* layer, int32 index)
63 return layer && AddItem((void*)layer, index);
66 // RemoveLayer
67 Layer*
68 Canvas::RemoveLayer(int32 index)
70 return (Layer*)RemoveItem(index);
73 // RemoveLayer
74 bool
75 Canvas::RemoveLayer(Layer* layer)
77 return RemoveItem((void*)layer);
80 // LayerAt
81 Layer*
82 Canvas::LayerAt(int32 index) const
84 return (Layer*)ItemAt(index);
87 // LayerAtFast
88 Layer*
89 Canvas::LayerAtFast(int32 index) const
91 return (Layer*)ItemAtFast(index);
94 // IndexOf
95 int32
96 Canvas::IndexOf(Layer* layer) const
98 return BList::IndexOf((void*)layer);
101 // CountLayers
102 int32
103 Canvas::CountLayers() const
105 return CountItems();
108 // HasLayer
109 bool
110 Canvas::HasLayer(Layer* layer) const
112 return HasItem((void*)layer);
115 // SetBounds
116 void
117 Canvas::SetBounds(BRect bounds)
119 if (bounds.IsValid())
120 fBounds = bounds;
123 // Bounds
124 BRect
125 Canvas::Bounds() const
127 return fBounds;
130 // Compose
131 void
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);
144 // Bitmap
145 BBitmap*
146 Canvas::Bitmap() const
148 BBitmap* bitmap = new BBitmap(fBounds, 0, B_RGBA32);
149 if (!bitmap->IsValid()) {
150 delete bitmap;
151 return NULL;
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;
162 while (height > 0) {
163 uint8* bitsHandle = bits;
164 for (uint32 x = 0; x < width; x++) {
165 if (!bitsHandle[3]) {
166 bitsHandle[0] = 0;
167 bitsHandle[1] = 0;
168 bitsHandle[2] = 0;
170 bitsHandle += 4;
172 bits += bpr;
173 height--;
176 return bitmap;
181 static const char* LAYER_KEY = "layer";
182 static const char* BOUNDS_KEY = "bounds";
184 // Unarchive
185 status_t
186 Canvas::Unarchive(const BMessage* archive)
188 if (!archive)
189 return B_BAD_VALUE;
191 // restore bounds
192 BRect bounds;
193 if (archive->FindRect(BOUNDS_KEY, &bounds) < B_OK)
194 return B_ERROR;
196 fBounds = bounds;
197 // restore each layer
198 BMessage layerMessage;
199 for (int32 i = 0;
200 archive->FindMessage(LAYER_KEY, i, &layerMessage) == B_OK;
201 i++) {
203 Layer* layer = new (nothrow) Layer();
204 if (!layer || layer->Unarchive(&layerMessage) < B_OK
205 || !AddLayer(layer)) {
206 delete layer;
207 return B_NO_MEMORY;
211 return B_OK;