зеркало из https://github.com/mozilla/pjs.git
Bug 549652: Properly support clearing surfaces. r=jrmuizel
This commit is contained in:
Родитель
40dfe937a9
Коммит
00ecc30146
|
@ -76,8 +76,11 @@ struct _cairo_d2d_surface {
|
|||
ID2D1Layer *clipLayer;
|
||||
/** Mask layer used by surface_mask to push opacity masks */
|
||||
ID2D1Layer *maskLayer;
|
||||
/** Layer used for clipping when tiling - lazily initialized */
|
||||
ID2D1Layer *tilingLayer;
|
||||
/**
|
||||
* Layer used for clipping when tiling, and also for clearing out geometries
|
||||
* - lazily initialized
|
||||
*/
|
||||
ID2D1Layer *helperLayer;
|
||||
/** If this layer currently is clipping, used to prevent excessive push/pops */
|
||||
bool clipping;
|
||||
/** Brush used for bitmaps */
|
||||
|
|
|
@ -846,15 +846,15 @@ _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
|||
D2DSurfFactory::Instance()->CreateRectangleGeometry(D2D1::RectF(0, 0, (float)width, (float)height),
|
||||
&clipRect);
|
||||
|
||||
if (!d2dsurf->tilingLayer) {
|
||||
d2dsurf->rt->CreateLayer(&d2dsurf->tilingLayer);
|
||||
if (!d2dsurf->helperLayer) {
|
||||
d2dsurf->rt->CreateLayer(&d2dsurf->helperLayer);
|
||||
}
|
||||
|
||||
d2dsurf->rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
|
||||
clipRect,
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||
_cairo_d2d_matrix_from_matrix(&mat)),
|
||||
d2dsurf->tilingLayer);
|
||||
d2dsurf->helperLayer);
|
||||
*pushed_clip = true;
|
||||
clipRect->Release();
|
||||
}
|
||||
|
@ -1137,6 +1137,27 @@ _cairo_d2d_create_path_geometry_for_path(cairo_path_fixed_t *path,
|
|||
return d2dpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* We use this to clear out a certain geometry on a surface. This will respect
|
||||
* the existing clip.
|
||||
*
|
||||
* \param d2dsurf Surface we clear
|
||||
* \param geometry Geometry of the area to clear
|
||||
*/
|
||||
static void _cairo_d2d_clear_geometry(cairo_d2d_surface_t *d2dsurf,
|
||||
ID2D1Geometry *geometry)
|
||||
{
|
||||
if (!d2dsurf->helperLayer) {
|
||||
d2dsurf->rt->CreateLayer(&d2dsurf->helperLayer);
|
||||
}
|
||||
|
||||
d2dsurf->rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
|
||||
geometry),
|
||||
d2dsurf->helperLayer);
|
||||
d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
|
||||
d2dsurf->rt->PopLayer();
|
||||
}
|
||||
|
||||
// Implementation
|
||||
static cairo_surface_t*
|
||||
_cairo_d2d_create_similar(void *surface,
|
||||
|
@ -1289,8 +1310,8 @@ _cairo_d2d_finish(void *surface)
|
|||
if (d2dsurf->surface) {
|
||||
d2dsurf->surface->Release();
|
||||
}
|
||||
if (d2dsurf->tilingLayer) {
|
||||
d2dsurf->tilingLayer->Release();
|
||||
if (d2dsurf->helperLayer) {
|
||||
d2dsurf->helperLayer->Release();
|
||||
}
|
||||
if (d2dsurf->bufferTexture) {
|
||||
d2dsurf->bufferTexture->Release();
|
||||
|
@ -1610,10 +1631,7 @@ _cairo_d2d_paint(void *surface,
|
|||
cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
|
||||
_begin_draw_state(d2dsurf);
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
cairo_solid_pattern_t *sourcePattern =
|
||||
(cairo_solid_pattern_t*)source;
|
||||
d2dsurf->rt->Clear(
|
||||
_cairo_d2d_color_from_cairo_color(sourcePattern->color));
|
||||
d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1755,14 +1773,14 @@ _cairo_d2d_stroke(void *surface,
|
|||
{
|
||||
cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
|
||||
_begin_draw_state(d2dsurf);
|
||||
if (op != CAIRO_OPERATOR_OVER && op != CAIRO_OPERATOR_SOURCE &&
|
||||
op != CAIRO_OPERATOR_ADD) {
|
||||
/**
|
||||
* We don't really support SOURCE and ADD yet. Source won't be
|
||||
* too hard, true ADD support requires getting the tesselated
|
||||
* mesh from D2D, and blending that using D3D which has an add
|
||||
* operator available.
|
||||
*/
|
||||
|
||||
if (op != CAIRO_OPERATOR_OVER && op != CAIRO_OPERATOR_ADD &&
|
||||
op != CAIRO_OPERATOR_CLEAR) {
|
||||
/**
|
||||
* We don't really support ADD yet. True ADD support requires getting
|
||||
* the tesselated mesh from D2D, and blending that using D3D which has
|
||||
* an add operator available.
|
||||
*/
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
@ -1779,6 +1797,29 @@ _cairo_d2d_stroke(void *surface,
|
|||
D2D1::Matrix3x2F mat = _cairo_d2d_matrix_from_matrix(ctm);
|
||||
|
||||
_cairo_path_fixed_transform(path, ctm_inverse);
|
||||
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
ID2D1Geometry *d2dpath = _cairo_d2d_create_path_geometry_for_path(path,
|
||||
CAIRO_FILL_RULE_WINDING,
|
||||
D2D1_FIGURE_BEGIN_FILLED);
|
||||
|
||||
ID2D1PathGeometry *strokeGeometry;
|
||||
D2DSurfFactory::Instance()->CreatePathGeometry(&strokeGeometry);
|
||||
|
||||
ID2D1GeometrySink *sink;
|
||||
strokeGeometry->Open(&sink);
|
||||
d2dpath->Widen((FLOAT)style->line_width, strokeStyle, mat, (FLOAT)tolerance, sink);
|
||||
sink->Close();
|
||||
sink->Release();
|
||||
|
||||
_cairo_d2d_clear_geometry(d2dsurf, strokeGeometry);
|
||||
|
||||
strokeGeometry->Release();
|
||||
d2dpath->Release();
|
||||
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
d2dsurf->rt->SetTransform(mat);
|
||||
|
||||
unsigned int runs_remaining = 1;
|
||||
|
@ -1862,13 +1903,12 @@ _cairo_d2d_fill(void *surface,
|
|||
cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
|
||||
_begin_draw_state(d2dsurf);
|
||||
|
||||
if (op != CAIRO_OPERATOR_OVER && op != CAIRO_OPERATOR_SOURCE &&
|
||||
op != CAIRO_OPERATOR_ADD) {
|
||||
if (op != CAIRO_OPERATOR_OVER && op != CAIRO_OPERATOR_ADD &&
|
||||
op != CAIRO_OPERATOR_CLEAR) {
|
||||
/**
|
||||
* We don't really support SOURCE and ADD yet. Source won't be
|
||||
* too hard, true ADD support requires getting the tesselated
|
||||
* mesh from D2D, and blending that using D3D which has an add
|
||||
* operator available.
|
||||
* We don't really support ADD yet. True ADD support requires getting
|
||||
* the tesselated mesh from D2D, and blending that using D3D which has
|
||||
* an add operator available.
|
||||
*/
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
@ -1883,6 +1923,16 @@ _cairo_d2d_fill(void *surface,
|
|||
unsigned int last_run = 0;
|
||||
bool pushed_clip = false;
|
||||
|
||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||
ID2D1Geometry *d2dpath = _cairo_d2d_create_path_geometry_for_path(path,
|
||||
fill_rule,
|
||||
D2D1_FIGURE_BEGIN_FILLED);
|
||||
_cairo_d2d_clear_geometry(d2dsurf, d2dpath);
|
||||
|
||||
d2dpath->Release();
|
||||
return CAIRO_INT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_box_t box;
|
||||
if (_cairo_path_fixed_is_box(path, &box)) {
|
||||
float x1 = _cairo_fixed_to_float(box.p1.x);
|
||||
|
|
Загрузка…
Ссылка в новой задаче