Index: core/cross/cairo/renderer_cairo.cc |
=================================================================== |
--- core/cross/cairo/renderer_cairo.cc (revision 57528) |
+++ core/cross/cairo/renderer_cairo.cc (working copy) |
@@ -37,6 +37,7 @@ |
#include <stdlib.h> |
#include <string.h> |
#include "core/cross/cairo/texture_cairo.h" |
+#include "core/cross/cairo/image_2d.h" |
namespace o3d { |
@@ -45,9 +46,7 @@ |
} |
RendererCairo::RendererCairo(ServiceLocator* service_locator) |
- : Renderer(service_locator), display_(NULL), window_(0), |
- main_surface_(NULL), frame_src_data_(NULL), frame_src_width_(0), |
- frame_src_height_(0), frame_src_pitch_(0) { |
+ : Renderer(service_locator), display_(NULL), main_surface_(NULL) { |
// Don't need to do anything. |
} |
@@ -69,55 +68,122 @@ |
} |
display_ = NULL; |
- frame_src_data_ = NULL; |
} |
-void RendererCairo::SetNewFrame(const void* src_data, unsigned src_width, |
- unsigned src_height, int src_pitch) { |
- DLOG(INFO) << "To Set New Frame"; |
- if (src_data == NULL) |
- return; |
- |
- frame_src_data_ = src_data; |
- frame_src_width_ = src_width; |
- frame_src_height_ = src_height; |
- frame_src_pitch_ = src_pitch; |
-} |
- |
// TODO(fransiskusx): Need to check if the shared memory data has been |
// unregistered. It will prevent errors when accessing unregistered |
// shared memory data to render the frame. |
void RendererCairo::Paint() { |
DLOG(INFO) << "To paint"; |
- if (frame_src_data_ != NULL) { |
- DLOG(INFO) << "To paint new drawing"; |
+ cairo_t* current_drawing = cairo_create(main_surface_); |
+ cairo_save(current_drawing); |
- // Preparing the image to render |
+ int arr_size = static_cast<int>(image_2d_array_.size()); |
+ |
+ // Update resource. |
+ for (int i = arr_size-1; i >= 0; i--) { |
+ Image2D* cur = image_2d_array_.at(i); |
+ cur->updateTextureResource(); |
+ } |
+ |
+ // Paint the background. |
+ PaintBackGround(current_drawing); |
+ |
+ // Core process of painting |
+ for (int i = arr_size-1; i >= 0 ; i--) { |
+ // Preparing and updating the image2d. |
+ Image2D* cur = image_2d_array_.at(i); |
+ |
+ // Check if the pointer to data is null. |
+ if (cur->src_data_ == NULL) { |
+ continue; |
+ } |
+ |
+ DLOG(INFO) << "INDEX = "<< i; |
+ |
+ DLOG(INFO) << cur->src_width_ << ", " << |
+ cur->src_height_<< ", " << cur->src_pitch_ << ", " << cur->scale_x_ << |
+ ", " << cur->scale_y_ << ", " << cur->translate_x_<< ", " << |
+ cur->translate_y_<< ", " << cur->dest_x_<< ", " << |
+ cur->dest_y_<< ", " << cur->alpha_ << "v3.5.7"; |
+ |
+ MaskArea(current_drawing, i); |
+ |
+ // Preparing the image to render. |
cairo_surface_t* image = cairo_image_surface_create_for_data( |
const_cast<unsigned char*>( |
- static_cast<const unsigned char*>(frame_src_data_)), |
- CAIRO_FORMAT_ARGB32, frame_src_width_, |
- frame_src_height_, frame_src_pitch_); |
- cairo_t* current_drawing = cairo_create(main_surface_); |
+ static_cast<const unsigned char*>(cur->src_data_)), |
+ CAIRO_FORMAT_ARGB32, cur->src_width_, |
+ cur->src_height_, cur->src_pitch_); |
- // Scaling the image |
+ // Scale the image. |
double width_scaling = |
- (static_cast<double>(display_width())) / frame_src_width_; |
+ (static_cast<double>(cur->scale_x_)) / cur->src_width_; |
double height_scaling = |
- (static_cast<double>(display_height())) / frame_src_height_; |
+ (static_cast<double>(cur->scale_y_)) / cur->src_height_; |
+ |
cairo_scale(current_drawing, width_scaling, height_scaling); |
- // Painting the image to the surface |
- cairo_set_source_surface(current_drawing, image, 0, 0); |
- cairo_paint(current_drawing); |
+ // Painting the image to the surface. |
+ cairo_set_source_surface(current_drawing, image, |
+ (cur->dest_x_+cur->translate_x_)/width_scaling, |
+ (cur->dest_y_+cur->translate_y_)/height_scaling); |
- // Cleaning up the memory |
- cairo_destroy(current_drawing); |
+ cairo_paint_with_alpha(current_drawing, cur->alpha_); |
+ |
+ // Cleaning up the memory. |
cairo_surface_destroy(image); |
+ |
+ // Restore to the state with no mask and put the state |
+ // back in the save stack. |
+ cairo_restore(current_drawing); |
+ cairo_save(current_drawing); |
} |
+ cairo_destroy(current_drawing); |
} |
+void RendererCairo::PaintBackGround(cairo_t* cr) { |
+ cairo_save(cr); |
+ MaskArea(cr, static_cast<int>(image_2d_array_.size())); |
+ |
+ cairo_rectangle(cr, 0, 0, display_width(), display_height()); |
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); |
+ cairo_fill(cr); |
+ cairo_restore(cr); |
+} |
+ |
+void RendererCairo::MaskArea(cairo_t* cr, int index) { |
+ // Check if the given index is out of bound(too big) for the image2d array. |
+ if (index > static_cast<int>(image_2d_array_.size())) { |
+ return; |
+ } |
+ |
+ cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); |
+ |
+ for (int j = index-1; j >= 0; j--) { |
+ // Preparing and updating the image2d. |
+ Image2D* curMask = image_2d_array_.at(j); |
+ |
+ DLOG(INFO) << curMask->dest_x_+curMask->translate_x_ << ", " << |
+ curMask->dest_y_+curMask->translate_y_<< ", " << |
+ static_cast<double>(curMask->scale_x_) << ", " << |
+ static_cast<double>(curMask->scale_y_) << "index = " << j; |
+ |
+ cairo_rectangle(cr, 0, 0, display_width(), display_height()); |
+ cairo_rectangle(cr, |
+ curMask->dest_x_+curMask->translate_x_, |
+ curMask->dest_y_+curMask->translate_y_, |
+ static_cast<double>(curMask->scale_x_), |
+ static_cast<double>(curMask->scale_y_)); |
+ cairo_clip(cr); |
+ } |
+} |
+ |
+void RendererCairo::AddImage2D(Image2D* image) { |
+ image_2d_array_.push_back(image); |
+} |
+ |
void RendererCairo::InitCommon() { |
main_surface_ = cairo_xlib_surface_create(display_, window_, |
XDefaultVisual(display_, 0), |
@@ -144,7 +210,7 @@ |
DLOG(INFO) << "To Resize " << width << " x " << height; |
SetClientSize(width, height); |
- // Resize the mainSurface |
+ // Resize the mainSurface and buffer |
cairo_xlib_surface_set_size(main_surface_, width, height); |
} |
@@ -189,6 +255,12 @@ |
} |
// TODO(fransiskusx): DO need to implement before shipped. |
+// Removes the Image2D from the array. |
+void RendererCairo::RemoveImage2D(Image2D* 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) { |
@@ -381,5 +453,9 @@ |
NOTIMPLEMENTED(); |
} |
+void RendererCairo::PopRenderStates() { |
+ NOTIMPLEMENTED(); |
+} |
+ |
} // namespace o3d |