summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--o3d/core/cross/cairo/layer.cc17
-rw-r--r--o3d/core/cross/cairo/layer.h13
-rw-r--r--o3d/core/cross/cairo/renderer_cairo.cc42
-rw-r--r--o3d/core/cross/cairo/renderer_cairo.h6
-rw-r--r--o3d/plugin/idl/layer.idl5
5 files changed, 64 insertions, 19 deletions
diff --git a/o3d/core/cross/cairo/layer.cc b/o3d/core/cross/cairo/layer.cc
index 3d536f0..7317dc1 100644
--- a/o3d/core/cross/cairo/layer.cc
+++ b/o3d/core/cross/cairo/layer.cc
@@ -42,16 +42,26 @@ namespace o2d {
O3D_DEFN_CLASS(Layer, ObjectBase);
+Layer::~Layer() {
+ Renderer* renderer = service_locator()->GetService<Renderer>();
+ RendererCairo* renderer_cairo = down_cast<RendererCairo*>(renderer);
+ renderer_cairo->RemoveLayer(this);
+}
+
Layer::Layer(ServiceLocator* service_locator)
: ObjectBase(service_locator),
alpha_(1.0),
x_(0),
y_(0),
+ z_(0),
width_(0),
height_(0),
scale_x_(1.0),
scale_y_(1.0) {
DLOG(INFO) << "Create Layer";
+ Renderer* renderer = service_locator->GetService<Renderer>();
+ RendererCairo* renderer_cairo = down_cast<RendererCairo*>(renderer);
+ renderer_cairo->AddLayer(this);
}
ObjectBase::Ref Layer::Create(ServiceLocator* service_locator) {
@@ -61,12 +71,9 @@ ObjectBase::Ref Layer::Create(ServiceLocator* service_locator) {
return ObjectBase::Ref();
}
- Layer* image = new Layer(service_locator);
-
- RendererCairo* renderer2d = down_cast<RendererCairo*>(renderer);
- renderer2d->AddLayer(image);
+ Layer* layer = new Layer(service_locator);
- return ObjectBase::Ref(image);
+ return ObjectBase::Ref(layer);
}
} // namespace o2d
diff --git a/o3d/core/cross/cairo/layer.h b/o3d/core/cross/cairo/layer.h
index 6408dc0..8e81206 100644
--- a/o3d/core/cross/cairo/layer.h
+++ b/o3d/core/cross/cairo/layer.h
@@ -50,6 +50,8 @@ class Layer : public ObjectBase {
public:
typedef SmartPointer<Layer> Ref;
+ virtual ~Layer();
+
Pattern* pattern() const {
return pattern_;
}
@@ -82,6 +84,14 @@ class Layer : public ObjectBase {
y_ = y;
}
+ double z() const {
+ return z_;
+ }
+
+ void set_z(double z) {
+ z_ = z;
+ }
+
double width() const {
return width_;
}
@@ -132,6 +142,9 @@ class Layer : public ObjectBase {
// The y coordinate of the top-left corner of this layer.
double y_;
+ // The z coordinate of the layer (used only to determine stacking order).
+ double z_;
+
// The width of this layer.
double width_;
diff --git a/o3d/core/cross/cairo/renderer_cairo.cc b/o3d/core/cross/cairo/renderer_cairo.cc
index 8bd698a..1cdc7e1 100644
--- a/o3d/core/cross/cairo/renderer_cairo.cc
+++ b/o3d/core/cross/cairo/renderer_cairo.cc
@@ -72,14 +72,28 @@ void RendererCairo::Destroy() {
display_ = NULL;
}
+// Comparison predicate for STL sort.
+bool LayerZValueLessThan(const Layer* first, const Layer* second) {
+ return first->z() < second->z();
+}
+
void RendererCairo::Paint() {
+ // TODO(tschmelcher): Don't keep creating and destroying the drawing context.
cairo_t* current_drawing = cairo_create(main_surface_);
+ // Redirect drawing to an off-screen surface (holding only colour information,
+ // without an alpha channel).
+ cairo_push_group_with_content(current_drawing, CAIRO_CONTENT_COLOR);
+
+ // Sort layers by z value.
+ // TODO(tschmelcher): Only sort when changes are made.
+ layer_list_.sort(LayerZValueLessThan);
+
// Paint the background.
PaintBackground(current_drawing);
// Core process of painting.
- for (LayerRefList::iterator i = layer_list_.begin();
+ for (LayerList::iterator i = layer_list_.begin();
i != layer_list_.end(); i++) {
// Put the state with no mask to the stack.
cairo_save(current_drawing);
@@ -93,7 +107,7 @@ void RendererCairo::Paint() {
}
// Masking areas for other scene.
- LayerRefList::iterator start_mask_it = i;
+ LayerList::iterator start_mask_it = i;
start_mask_it++;
MaskArea(current_drawing, start_mask_it);
@@ -109,6 +123,14 @@ void RendererCairo::Paint() {
// Restore to the state with no mask.
cairo_restore(current_drawing);
}
+
+ // Finish off-screen drawing and make the off-screen surface the source for
+ // paints to the screen.
+ cairo_pop_group_to_source(current_drawing);
+
+ // Paint the off-screen surface to the screen.
+ cairo_paint(current_drawing);
+
cairo_destroy(current_drawing);
}
@@ -122,10 +144,10 @@ void RendererCairo::PaintBackground(cairo_t* cr) {
cairo_restore(cr);
}
-void RendererCairo::MaskArea(cairo_t* cr, LayerRefList::iterator it) {
+void RendererCairo::MaskArea(cairo_t* cr, LayerList::iterator it) {
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
- for (LayerRefList::iterator i = it; i != layer_list_.end(); i++) {
+ for (LayerList::iterator i = it; i != layer_list_.end(); i++) {
// Preparing and updating the Layer.
Layer* cur_mask = *i;
@@ -140,7 +162,11 @@ void RendererCairo::MaskArea(cairo_t* cr, LayerRefList::iterator it) {
}
void RendererCairo::AddLayer(Layer* image) {
- layer_list_.push_front(Layer::Ref(image));
+ layer_list_.push_front(image);
+}
+
+void RendererCairo::RemoveLayer(Layer* image) {
+ layer_list_.remove(image);
}
void RendererCairo::InitCommon() {
@@ -214,12 +240,6 @@ void RendererCairo::PlatformSpecificPresent() {
}
// TODO(fransiskusx): DO need to implement before shipped.
-// Removes the Layer from the array.
-void RendererCairo::RemoveLayer(Layer* image) {
- NOTIMPLEMENTED();
-}
-
-// TODO(fransiskusx): DO need to implement before shipped.
// Get a single fullscreen display mode by id.
// Returns true on success, false on error.
bool RendererCairo::GetDisplayMode(int id, DisplayMode* mode) {
diff --git a/o3d/core/cross/cairo/renderer_cairo.h b/o3d/core/cross/cairo/renderer_cairo.h
index f62698a..e985dc1 100644
--- a/o3d/core/cross/cairo/renderer_cairo.h
+++ b/o3d/core/cross/cairo/renderer_cairo.h
@@ -152,7 +152,7 @@ class RendererCairo : public Renderer {
void PopRenderStates();
protected:
- typedef std::list<Layer::Ref> LayerRefList;
+ typedef std::list<Layer*> LayerList;
// Keep the constructor protected so only factory methods can create
// renderers.
@@ -219,7 +219,7 @@ class RendererCairo : public Renderer {
float max_z);
// Mask the area of the current layer that will collide with other images.
- void MaskArea(cairo_t* cr, LayerRefList::iterator it);
+ void MaskArea(cairo_t* cr, LayerList::iterator it);
// Paint the background with black color.
// TODO(fransiskusx): Support changing the background color.
@@ -237,7 +237,7 @@ class RendererCairo : public Renderer {
cairo_t* bg_drawing_;
// Array of Layer
- LayerRefList layer_list_;
+ LayerList layer_list_;
};
} // namespace o2d
diff --git a/o3d/plugin/idl/layer.idl b/o3d/plugin/idl/layer.idl
index 964feaf..3a479ba 100644
--- a/o3d/plugin/idl/layer.idl
+++ b/o3d/plugin/idl/layer.idl
@@ -59,6 +59,11 @@ namespace o2d {
[getter, setter] double y;
%[
+ The z coordinate of the layer (used only to determine stacking order).
+ %]
+ [getter, setter] double z;
+
+ %[
The width of this layer.
%]
[getter, setter] double width;