Index: core/cross/cairo/renderer_cairo.cc |
=================================================================== |
--- core/cross/cairo/renderer_cairo.cc (revision 71475) |
+++ core/cross/cairo/renderer_cairo.cc (working copy) |
@@ -1,5 +1,5 @@ |
/* |
- * Copyright 2010, Google Inc. |
+ * Copyright 2011, Google Inc. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
@@ -95,32 +95,64 @@ |
// Core process of painting. |
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); |
+ Layer* cur = *i; |
+ if (!cur->ShouldPaint()) continue; |
- // Preparing and updating the Layer. |
- Layer* cur = *i; |
Pattern* pattern = cur->pattern(); |
- if (!pattern) { |
- // Skip layers with no pattern assigned. |
- continue; |
- } |
- // Masking areas for other scene. |
+ // Save the current drawing state. |
+ cairo_save(current_drawing); |
+ |
+ // Clip areas that will be obscured anyway. |
LayerList::iterator start_mask_it = i; |
start_mask_it++; |
- MaskArea(current_drawing, start_mask_it); |
+ ClipArea(current_drawing, start_mask_it); |
+ // Define the region to fill. |
+ cairo_rectangle(current_drawing, |
+ cur->x(), |
+ cur->y(), |
+ cur->width(), |
+ cur->height()); |
+ |
+ // Transform the pattern to fit into the fill region. |
cairo_translate(current_drawing, cur->x(), cur->y()); |
- |
cairo_scale(current_drawing, cur->scale_x(), cur->scale_y()); |
- // Painting the image to the surface. |
+ // Set source pattern. |
cairo_set_source(current_drawing, pattern->pattern()); |
- cairo_paint_with_alpha(current_drawing, cur->alpha()); |
+ // Paint the pattern to the off-screen surface. |
+ switch (cur->paint_operator()) { |
+ case Layer::BLEND: |
+ cairo_fill(current_drawing); |
+ break; |
- // Restore to the state with no mask. |
+ case Layer::BLEND_WITH_TRANSPARENCY: |
+ { |
+ cairo_pattern_t* mask = cairo_pattern_create_rgba(0.0, |
+ 0.0, |
+ 0.0, |
+ cur->alpha()); |
+ cairo_mask(current_drawing, mask); |
+ cairo_pattern_destroy(mask); |
+ } |
+ break; |
+ |
+ // TODO(tschmelcher): COPY_WITH_FADING is not implemented yet. For now |
+ // we treat it the same as COPY. |
+ case Layer::COPY_WITH_FADING: |
+ case Layer::COPY: |
+ // Set Cairo to copy the pattern's alpha content instead of blending. |
+ cairo_set_operator(current_drawing, CAIRO_OPERATOR_SOURCE); |
+ cairo_fill(current_drawing); |
+ break; |
+ |
+ default: |
+ DCHECK(false); |
+ } |
+ |
+ // Restore to a clean state. |
cairo_restore(current_drawing); |
} |
@@ -136,7 +168,7 @@ |
void RendererCairo::PaintBackground(cairo_t* cr) { |
cairo_save(cr); |
- MaskArea(cr, layer_list_.begin()); |
+ ClipArea(cr, layer_list_.begin()); |
cairo_rectangle(cr, 0, 0, display_width(), display_height()); |
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); |
@@ -144,19 +176,20 @@ |
cairo_restore(cr); |
} |
-void RendererCairo::MaskArea(cairo_t* cr, LayerList::iterator it) { |
+void RendererCairo::ClipArea(cairo_t* cr, LayerList::iterator it) { |
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); |
for (LayerList::iterator i = it; i != layer_list_.end(); i++) { |
// Preparing and updating the Layer. |
- Layer* cur_mask = *i; |
+ Layer* cur = *i; |
+ if (!cur->ShouldClip()) continue; |
cairo_rectangle(cr, 0, 0, display_width(), display_height()); |
cairo_rectangle(cr, |
- cur_mask->x(), |
- cur_mask->y(), |
- cur_mask->width(), |
- cur_mask->height()); |
+ cur->x(), |
+ cur->y(), |
+ cur->width(), |
+ cur->height()); |
cairo_clip(cr); |
} |
} |