| 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);
|
| }
|
| }
|
|
|