summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authortschmelcher@chromium.org <tschmelcher@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-20 21:41:51 +0000
committertschmelcher@chromium.org <tschmelcher@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-20 21:41:51 +0000
commitee383ec41ac64fa524998fed735f5cafa1b11214 (patch)
tree8c351d77756b31b87de26e69d0672b6a7708d230 /o3d
parent1d0bb92191e7c495f29ef71bedda2ef4c72eb8aa (diff)
downloadchromium_src-ee383ec41ac64fa524998fed735f5cafa1b11214.zip
chromium_src-ee383ec41ac64fa524998fed735f5cafa1b11214.tar.gz
chromium_src-ee383ec41ac64fa524998fed735f5cafa1b11214.tar.bz2
O2D:
- New APIs: - Add a "visible" property to the Layer class to mimick the visible property of the Transform class. - Add a method to set an affine transform on Pattern objects so that texture patterns can be transformed independently from the Layers that use them. - Add a "paint operators" API for Layers and define four operators (currently only three of them implemented). The previous hard-coded behaviour was equivalent to the BLEND_WITH_TRANSPARENCY operator. - Fixes: - Replace the "mask" nomenclature with "clip", which is a more standard name. - Don't clip alpha-blended layers. - Restrict Layer painting to the rectangle defined by the attributes. - Set default alpha value to 0.0 instead of 1.0 to match what JavaScript expects. TEST=loaded O2D and verified all new functionality is working BUG=none Review URL: http://codereview.chromium.org/6255003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72006 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/core/cross/cairo/layer.cc6
-rw-r--r--o3d/core/cross/cairo/layer.h50
-rw-r--r--o3d/core/cross/cairo/pattern.cc11
-rw-r--r--o3d/core/cross/cairo/pattern.h10
-rw-r--r--o3d/core/cross/cairo/renderer_cairo.cc77
-rw-r--r--o3d/core/cross/cairo/renderer_cairo.h4
-rw-r--r--o3d/plugin/idl/layer.idl35
-rw-r--r--o3d/plugin/idl/pattern.idl18
8 files changed, 183 insertions, 28 deletions
diff --git a/o3d/core/cross/cairo/layer.cc b/o3d/core/cross/cairo/layer.cc
index 7317dc1..943308f 100644
--- a/o3d/core/cross/cairo/layer.cc
+++ b/o3d/core/cross/cairo/layer.cc
@@ -50,14 +50,16 @@ Layer::~Layer() {
Layer::Layer(ServiceLocator* service_locator)
: ObjectBase(service_locator),
- alpha_(1.0),
+ visible_(true),
+ alpha_(0.0),
x_(0),
y_(0),
z_(0),
width_(0),
height_(0),
scale_x_(1.0),
- scale_y_(1.0) {
+ scale_y_(1.0),
+ paint_operator_(BLEND) {
DLOG(INFO) << "Create Layer";
Renderer* renderer = service_locator->GetService<Renderer>();
RendererCairo* renderer_cairo = down_cast<RendererCairo*>(renderer);
diff --git a/o3d/core/cross/cairo/layer.h b/o3d/core/cross/cairo/layer.h
index 8e81206..df2832b 100644
--- a/o3d/core/cross/cairo/layer.h
+++ b/o3d/core/cross/cairo/layer.h
@@ -50,8 +50,17 @@ class Layer : public ObjectBase {
public:
typedef SmartPointer<Layer> Ref;
+ enum PaintOperator {
+ BLEND,
+ BLEND_WITH_TRANSPARENCY,
+ COPY,
+ COPY_WITH_FADING,
+ };
+
virtual ~Layer();
+ // Methods exposed to JS.
+
Pattern* pattern() const {
return pattern_;
}
@@ -60,6 +69,14 @@ class Layer : public ObjectBase {
pattern_ = Pattern::Ref(pattern);
}
+ bool visible() const {
+ return visible_;
+ }
+
+ void set_visible(bool visible) {
+ visible_ = visible;
+ }
+
double alpha() const {
return alpha_;
}
@@ -124,6 +141,30 @@ class Layer : public ObjectBase {
scale_y_ = scale_y;
}
+ PaintOperator paint_operator() const {
+ return paint_operator_;
+ }
+
+ void set_paint_operator(PaintOperator paint_operator) {
+ paint_operator_ = paint_operator;
+ }
+
+ // Methods not exposed to JS.
+
+ // Whether we should currently paint this layer.
+ bool ShouldPaint() const {
+ return visible() && pattern() != NULL;
+ }
+
+ // Whether this layer should currently clip content behind it (i.e.,
+ // prevent it from being drawn in the first place).
+ bool ShouldClip() const {
+ // When alpha blending is used we cannot clip the background because our
+ // content will be blended with it.
+ return ShouldPaint() &&
+ (paint_operator() == COPY || paint_operator() == COPY_WITH_FADING);
+ }
+
private:
explicit Layer(ServiceLocator* service_locator);
@@ -133,7 +174,11 @@ class Layer : public ObjectBase {
// The pattern used to paint this Layer.
Pattern::Ref pattern_;
- // Transparancy of this layer.
+ // Whether this layer should be visible or not.
+ bool visible_;
+
+ // The transparency for the BLEND_WITH_TRANSPARENCY operator or the fading for
+ // the COPY_WITH_FADING operator.
double alpha_;
// The x coordinate of the top-left corner of this layer.
@@ -157,6 +202,9 @@ class Layer : public ObjectBase {
// A scaling factor to apply to the pattern's y-axis.
double scale_y_;
+ // The paint operator to use for painting this Layer.
+ PaintOperator paint_operator_;
+
O3D_DECL_CLASS(Layer, ObjectBase)
}; // Layer
diff --git a/o3d/core/cross/cairo/pattern.cc b/o3d/core/cross/cairo/pattern.cc
index 8a59d3e..93c7582 100644
--- a/o3d/core/cross/cairo/pattern.cc
+++ b/o3d/core/cross/cairo/pattern.cc
@@ -73,6 +73,17 @@ Pattern::~Pattern() {
cairo_pattern_destroy(pattern_);
}
+void Pattern::SetAffineTransform(double xx,
+ double yx,
+ double xy,
+ double yy,
+ double x0,
+ double y0) {
+ cairo_matrix_t matrix;
+ cairo_matrix_init(&matrix, xx, yx, xy, yy, x0, y0);
+ cairo_pattern_set_matrix(pattern_, &matrix);
+}
+
Pattern::Pattern(ServiceLocator* service_locator, cairo_pattern_t* pattern)
: ObjectBase(service_locator),
pattern_(pattern) {
diff --git a/o3d/core/cross/cairo/pattern.h b/o3d/core/cross/cairo/pattern.h
index 8828c6d..fbb91d3 100644
--- a/o3d/core/cross/cairo/pattern.h
+++ b/o3d/core/cross/cairo/pattern.h
@@ -69,6 +69,16 @@ class Pattern : public ObjectBase {
cairo_pattern_t* pattern() const { return pattern_; }
+ // Set the affine transformation matrix that maps user space to pattern space.
+ // The default matrix is the identity matrix, so that no transformation
+ // occurs.
+ void SetAffineTransform(double xx,
+ double yx,
+ double xy,
+ double yy,
+ double x0,
+ double y0);
+
private:
Pattern(ServiceLocator* service_locator, cairo_pattern_t* pattern);
diff --git a/o3d/core/cross/cairo/renderer_cairo.cc b/o3d/core/cross/cairo/renderer_cairo.cc
index 1cdc7e1..dabf61b 100644
--- a/o3d/core/cross/cairo/renderer_cairo.cc
+++ b/o3d/core/cross/cairo/renderer_cairo.cc
@@ -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 @@ void RendererCairo::Paint() {
// 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);
-
- // Preparing and updating the Layer.
Layer* cur = *i;
+ if (!cur->ShouldPaint()) continue;
+
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);
- cairo_translate(current_drawing, cur->x(), cur->y());
+ // 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;
+
+ 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 the state with no mask.
+ // Restore to a clean state.
cairo_restore(current_drawing);
}
@@ -136,7 +168,7 @@ void RendererCairo::Paint() {
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 @@ void RendererCairo::PaintBackground(cairo_t* cr) {
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);
}
}
diff --git a/o3d/core/cross/cairo/renderer_cairo.h b/o3d/core/cross/cairo/renderer_cairo.h
index e985dc1..ced0d5e 100644
--- a/o3d/core/cross/cairo/renderer_cairo.h
+++ b/o3d/core/cross/cairo/renderer_cairo.h
@@ -218,8 +218,8 @@ class RendererCairo : public Renderer {
float min_z,
float max_z);
- // Mask the area of the current layer that will collide with other images.
- void MaskArea(cairo_t* cr, LayerList::iterator it);
+ // Clip the area of the current layer that will collide with other images.
+ void ClipArea(cairo_t* cr, LayerList::iterator it);
// Paint the background with black color.
// TODO(fransiskusx): Support changing the background color.
diff --git a/o3d/plugin/idl/layer.idl b/o3d/plugin/idl/layer.idl
index 3a479ba..ef28380 100644
--- a/o3d/plugin/idl/layer.idl
+++ b/o3d/plugin/idl/layer.idl
@@ -39,12 +39,40 @@ namespace o2d {
%]
[nocpp, include="core/cross/cairo/layer.h"] class Layer : ObjectBase {
%[
+ Available painting operators.
+
+ \var PaintOperator,
+ \li BLEND, Alpha-blend the Pattern on top of lower Layers based on its
+ alpha channel. (Default)
+ \li BLEND_WITH_TRANSPARENCY, Like BLEND, but scale the alpha channel down
+ based on the alpha property of the Layer as an
+ additional fractional transparency.
+ \li COPY, Copy the colour content of the Pattern directly to the
+ destination, ignoring the alpha channel.
+ \li COPY_WITH_FADING, Like COPY, but fade the colour to black based on the
+ alpha property of the Layer as an additional
+ fractional brightness.
+ %]
+ enum PaintOperator {
+ BLEND,
+ BLEND_WITH_TRANSPARENCY,
+ COPY,
+ COPY_WITH_FADING
+ };
+
+ %[
The Pattern used to paint this Layer.
%]
[getter, setter] Pattern? pattern;
%[
- Transparancy of this layer.
+ Whether this layer should be visible or not.
+ %]
+ [getter, setter] bool visible;
+
+ %[
+ The transparency for the BLEND_WITH_TRANSPARENCY operator or the fading for
+ the COPY_WITH_FADING operator.
%]
[getter, setter] double alpha;
@@ -82,6 +110,11 @@ namespace o2d {
A scaling factor to apply to the pattern's y-axis.
%]
[getter, setter] double scale_y;
+
+ %[
+ The paint operator to use for painting this Layer.
+ %]
+ [getter, setter] PaintOperator paint_operator;
}; // Layer
} // namespace o2d
diff --git a/o3d/plugin/idl/pattern.idl b/o3d/plugin/idl/pattern.idl
index c511809..bed3daf 100644
--- a/o3d/plugin/idl/pattern.idl
+++ b/o3d/plugin/idl/pattern.idl
@@ -75,6 +75,24 @@ namespace o2d {
double green,
double blue,
double alpha);
+
+ %[
+ Set the affine transformation matrix that maps user space to pattern space.
+ The default matrix is the identity matrix, so that no transformation occurs.
+
+ \param xx xx component of the affine transformation
+ \param yx yx component of the affine transformation
+ \param xy xy component of the affine transformation
+ \param yy yy component of the affine transformation
+ \param x0 X translation component of the affine transformation
+ \param y0 Y translation component of the affine transformation
+ %]
+ void SetAffineTransform(double xx,
+ double yx,
+ double xy,
+ double yy,
+ double x0,
+ double y0);
}; // Pattern
} // namespace o2d