Bug 587316 - Part 3: Allow custom operators when doing masking. r=jrmuizel
authorBas Schouten <bschouten@mozilla.com>
Mon, 16 Aug 2010 09:15:02 +0200
changeset 50650 1d7c15818f663035ce835a7c336d6d0496a7fe54
parent 50649 ea6bbdbf14906e86599d3648594ad5aefc322321
child 50651 055a407bb683d9e5d567d9972446dd1d5d61cd83
push idunknown
push userunknown
push dateunknown
reviewersjrmuizel
bugs587316
milestone2.0b4pre
Bug 587316 - Part 3: Allow custom operators when doing masking. r=jrmuizel
gfx/cairo/cairo/src/cairo-d2d-surface.cpp
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
+++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
@@ -2948,22 +2948,33 @@ static cairo_int_status_t
 		const cairo_pattern_t	*mask,
 		cairo_clip_t		*clip)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     cairo_rectangle_int_t extents;
 
     cairo_int_status_t status;
 
-    _begin_draw_state(d2dsurf);
-    status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
-
-    if (unlikely (status))
-	return status;
-
+    RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt;
+#ifndef ALWAYS_MANUAL_COMPOSITE
+    if (op != CAIRO_OPERATOR_OVER) {
+#endif
+	target_rt = _cairo_d2d_get_temp_rt(d2dsurf, clip);
+	if (!target_rt) {
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	}
+#ifndef ALWAYS_MANUAL_COMPOSITE
+    } else {
+	_begin_draw_state(d2dsurf);
+	status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
+
+	if (unlikely(status))
+	    return status;
+    }
+#endif
 
     status = (cairo_int_status_t)_cairo_surface_mask_extents (&d2dsurf->base,
 		    op, source,
 		    mask,
 		    clip, &extents);
     if (unlikely (status))
 	    return status;
 
@@ -2984,42 +2995,50 @@ static cairo_int_status_t
     rect.bottom = (FLOAT)(extents.y + extents.height);
 
 
     if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
 	cairo_solid_pattern_t *solidPattern =
 	    (cairo_solid_pattern_t*)mask;
 	if (solidPattern->content = CAIRO_CONTENT_ALPHA) {
 	    brush->SetOpacity((FLOAT)solidPattern->color.alpha);
-	    d2dsurf->rt->FillRectangle(rect,
-				       brush);
+	    target_rt->FillRectangle(rect,
+				     brush);
 	    brush->SetOpacity(1.0);
+
+	    if (target_rt.get() != d2dsurf->rt.get()) {
+		return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
+	    }
 	    return CAIRO_INT_STATUS_SUCCESS;
 	}
     }
 
     RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, mask, true);
     if (!opacityBrush) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
     if (!d2dsurf->maskLayer) {
 	d2dsurf->rt->CreateLayer(&d2dsurf->maskLayer);
     }
-    d2dsurf->rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
-						 0,
-						 D2D1_ANTIALIAS_MODE_ALIASED,
-						 D2D1::IdentityMatrix(),
-						 1.0,
-						 opacityBrush),
-			   d2dsurf->maskLayer);
-
-    d2dsurf->rt->FillRectangle(rect,
-			       brush);
-    d2dsurf->rt->PopLayer();
+    target_rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
+					       0,
+					       D2D1_ANTIALIAS_MODE_ALIASED,
+					       D2D1::IdentityMatrix(),
+					       1.0,
+					       opacityBrush),
+			 d2dsurf->maskLayer);
+
+    target_rt->FillRectangle(rect,
+			     brush);
+    target_rt->PopLayer();
+
+    if (target_rt.get() != d2dsurf->rt.get()) {
+	return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
+    }
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_d2d_stroke(void			*surface,
 		  cairo_operator_t	 op,
 		  const cairo_pattern_t	*source,
 		  cairo_path_fixed_t	*path,