зеркало из https://github.com/mozilla/pjs.git
[qpainter] Use drawImage/drawPixmap in fill() for non-repeating sources
This commit is contained in:
Родитель
aa4f8c4621
Коммит
3e2223f406
|
@ -92,6 +92,10 @@ typedef struct {
|
||||||
bool has_clipping;
|
bool has_clipping;
|
||||||
QRect clip_bounds;
|
QRect clip_bounds;
|
||||||
|
|
||||||
|
// if this is true, calls to intersect_clip_path won't
|
||||||
|
// update the clip_bounds rect
|
||||||
|
bool no_update_clip_bounds;
|
||||||
|
|
||||||
cairo_image_surface_t *image_equiv;
|
cairo_image_surface_t *image_equiv;
|
||||||
|
|
||||||
#if defined(Q_WS_X11) && defined(CAIRO_HAS_XLIB_XRENDER_SURFACE)
|
#if defined(Q_WS_X11) && defined(CAIRO_HAS_XLIB_XRENDER_SURFACE)
|
||||||
|
@ -654,10 +658,10 @@ _cairo_qpainter_surface_get_extents (void *abstract_surface,
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_qpainter_surface_intersect_clip_path (void *abstract_surface,
|
_cairo_qpainter_surface_intersect_clip_path (void *abstract_surface,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias)
|
cairo_antialias_t antialias)
|
||||||
{
|
{
|
||||||
cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t *) abstract_surface;
|
cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t *) abstract_surface;
|
||||||
|
|
||||||
|
@ -677,8 +681,10 @@ _cairo_qpainter_surface_intersect_clip_path (void *abstract_surface,
|
||||||
qs->p->save ();
|
qs->p->save ();
|
||||||
}
|
}
|
||||||
|
|
||||||
qs->clip_bounds.setRect(0, 0, 0, 0);
|
if (!qs->no_update_clip_bounds) {
|
||||||
qs->has_clipping = false;
|
qs->clip_bounds.setRect(0, 0, 0, 0);
|
||||||
|
qs->has_clipping = false;
|
||||||
|
}
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -777,13 +783,15 @@ _cairo_qpainter_surface_intersect_clip_path (void *abstract_surface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clip_bounds = qs->p->worldTransform().mapRect(clip_bounds);
|
if (!qs->no_update_clip_bounds) {
|
||||||
|
clip_bounds = qs->p->worldTransform().mapRect(clip_bounds);
|
||||||
|
|
||||||
if (qs->has_clipping) {
|
if (qs->has_clipping) {
|
||||||
qs->clip_bounds = qs->clip_bounds.intersect(clip_bounds);
|
qs->clip_bounds = qs->clip_bounds.intersect(clip_bounds);
|
||||||
} else {
|
} else {
|
||||||
qs->clip_bounds = clip_bounds;
|
qs->clip_bounds = clip_bounds;
|
||||||
qs->has_clipping = true;
|
qs->has_clipping = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tend("clip");
|
tend("clip");
|
||||||
|
@ -1142,6 +1150,7 @@ _cairo_qpainter_surface_fill (void *abstract_surface,
|
||||||
cairo_antialias_t antialias)
|
cairo_antialias_t antialias)
|
||||||
{
|
{
|
||||||
cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t *) abstract_surface;
|
cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t *) abstract_surface;
|
||||||
|
cairo_qpainter_surface_t *qsSrc = NULL;
|
||||||
|
|
||||||
D(fprintf(stderr, "q[%p] fill op:%s\n", abstract_surface, _opstr(op)));
|
D(fprintf(stderr, "q[%p] fill op:%s\n", abstract_surface, _opstr(op)));
|
||||||
|
|
||||||
|
@ -1150,10 +1159,6 @@ _cairo_qpainter_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
tstart();
|
tstart();
|
||||||
|
|
||||||
QPainterPath qpath;
|
|
||||||
if (_cairo_quartz_cairo_path_to_qpainterpath (path, &qpath, fill_rule) != CAIRO_STATUS_SUCCESS)
|
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
||||||
|
|
||||||
if (qs->supports_porter_duff)
|
if (qs->supports_porter_duff)
|
||||||
qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op));
|
qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op));
|
||||||
|
|
||||||
|
@ -1162,30 +1167,56 @@ _cairo_qpainter_surface_fill (void *abstract_surface,
|
||||||
//qs->p->setRenderHint (QPainter::Antialiasing, antialias == CAIRO_ANTIALIAS_NONE ? false : true);
|
//qs->p->setRenderHint (QPainter::Antialiasing, antialias == CAIRO_ANTIALIAS_NONE ? false : true);
|
||||||
qs->p->setRenderHint (QPainter::SmoothPixmapTransform, source->filter != CAIRO_FILTER_FAST);
|
qs->p->setRenderHint (QPainter::SmoothPixmapTransform, source->filter != CAIRO_FILTER_FAST);
|
||||||
|
|
||||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
|
// Check if the source is a qpainter surface for which we have a QImage
|
||||||
source->extend == CAIRO_EXTEND_NONE &&
|
// or QPixmap
|
||||||
((cairo_surface_pattern_t*)source)->surface->type == CAIRO_SURFACE_TYPE_QPAINTER)
|
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||||
|
cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) source;
|
||||||
|
if (spattern->surface->type == CAIRO_SURFACE_TYPE_QPAINTER) {
|
||||||
|
cairo_qpainter_surface_t *p = (cairo_qpainter_surface_t*) spattern->surface;
|
||||||
|
|
||||||
|
if (p->image || p->pixmap)
|
||||||
|
qsSrc = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qsSrc && source->extend == CAIRO_EXTEND_NONE)
|
||||||
{
|
{
|
||||||
cairo_qpainter_surface_t *qsSrc = (cairo_qpainter_surface_t*) ((cairo_surface_pattern_t*)source)->surface;
|
QMatrix sourceMatrix = _qmatrix_from_cairo_matrix (source->matrix);
|
||||||
|
cairo_int_status_t status;
|
||||||
|
|
||||||
QMatrix savedMatrix = qs->p->worldMatrix();
|
// We can draw this faster by clipping and calling drawImage/drawPixmap.
|
||||||
cairo_matrix_t m = source->matrix;
|
// Use our own clipping function so that we can get the
|
||||||
cairo_matrix_invert (&m);
|
// region handling to end up with the fastest possible clip.
|
||||||
qs->p->setWorldMatrix (_qmatrix_from_cairo_matrix (m), true);
|
//
|
||||||
|
// XXX Antialiasing will fail pretty hard here, since we can't clip with AA
|
||||||
|
// with QPainter.
|
||||||
|
qs->p->save();
|
||||||
|
|
||||||
if (qsSrc->image) {
|
qs->no_update_clip_bounds = true;
|
||||||
qs->p->drawImage (0, 0, *qsSrc->image);
|
status = _cairo_qpainter_surface_intersect_clip_path (qs, path, fill_rule, tolerance, antialias);
|
||||||
} else if (qsSrc->pixmap) {
|
qs->no_update_clip_bounds = false;
|
||||||
qs->p->drawPixmap (0, 0, *qsSrc->pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
qs->p->setWorldMatrix (savedMatrix, false);
|
if (status != CAIRO_INT_STATUS_SUCCESS) {
|
||||||
|
qs->p->restore();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
qs->p->setWorldMatrix (sourceMatrix.inverted(), true);
|
||||||
|
|
||||||
|
if (qsSrc->image) {
|
||||||
|
qs->p->drawImage (0, 0, *qsSrc->image);
|
||||||
|
} else if (qsSrc->pixmap) {
|
||||||
|
qs->p->drawPixmap (0, 0, *qsSrc->pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
qs->p->restore();
|
||||||
} else {
|
} else {
|
||||||
|
QPainterPath qpath;
|
||||||
|
if (_cairo_quartz_cairo_path_to_qpainterpath (path, &qpath, fill_rule) != CAIRO_STATUS_SUCCESS)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
PatternToBrushConverter brush(source);
|
PatternToBrushConverter brush(source);
|
||||||
|
qs->p->fillPath (qpath, brush);
|
||||||
qs->p->fillPath (qpath, brush);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qs->supports_porter_duff)
|
if (qs->supports_porter_duff)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче