[qpainter] Use drawImage/drawPixmap in fill() for non-repeating sources

This commit is contained in:
Vladimir Vukicevic 2008-05-01 11:54:35 -07:00
Родитель aa4f8c4621
Коммит 3e2223f406
1 изменённых файлов: 65 добавлений и 34 удалений

Просмотреть файл

@ -92,6 +92,10 @@ typedef struct {
bool has_clipping;
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;
#if defined(Q_WS_X11) && defined(CAIRO_HAS_XLIB_XRENDER_SURFACE)
@ -677,8 +681,10 @@ _cairo_qpainter_surface_intersect_clip_path (void *abstract_surface,
qs->p->save ();
}
if (!qs->no_update_clip_bounds) {
qs->clip_bounds.setRect(0, 0, 0, 0);
qs->has_clipping = false;
}
return CAIRO_INT_STATUS_SUCCESS;
}
@ -777,6 +783,7 @@ _cairo_qpainter_surface_intersect_clip_path (void *abstract_surface,
}
}
if (!qs->no_update_clip_bounds) {
clip_bounds = qs->p->worldTransform().mapRect(clip_bounds);
if (qs->has_clipping) {
@ -785,6 +792,7 @@ _cairo_qpainter_surface_intersect_clip_path (void *abstract_surface,
qs->clip_bounds = clip_bounds;
qs->has_clipping = true;
}
}
tend("clip");
@ -1142,6 +1150,7 @@ _cairo_qpainter_surface_fill (void *abstract_surface,
cairo_antialias_t antialias)
{
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)));
@ -1150,10 +1159,6 @@ _cairo_qpainter_surface_fill (void *abstract_surface,
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)
qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op));
@ -1162,16 +1167,41 @@ _cairo_qpainter_surface_fill (void *abstract_surface,
//qs->p->setRenderHint (QPainter::Antialiasing, antialias == CAIRO_ANTIALIAS_NONE ? false : true);
qs->p->setRenderHint (QPainter::SmoothPixmapTransform, source->filter != CAIRO_FILTER_FAST);
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
source->extend == CAIRO_EXTEND_NONE &&
((cairo_surface_pattern_t*)source)->surface->type == CAIRO_SURFACE_TYPE_QPAINTER)
{
cairo_qpainter_surface_t *qsSrc = (cairo_qpainter_surface_t*) ((cairo_surface_pattern_t*)source)->surface;
// Check if the source is a qpainter surface for which we have a QImage
// or QPixmap
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;
QMatrix savedMatrix = qs->p->worldMatrix();
cairo_matrix_t m = source->matrix;
cairo_matrix_invert (&m);
qs->p->setWorldMatrix (_qmatrix_from_cairo_matrix (m), true);
if (p->image || p->pixmap)
qsSrc = p;
}
}
if (qsSrc && source->extend == CAIRO_EXTEND_NONE)
{
QMatrix sourceMatrix = _qmatrix_from_cairo_matrix (source->matrix);
cairo_int_status_t status;
// We can draw this faster by clipping and calling drawImage/drawPixmap.
// Use our own clipping function so that we can get the
// region handling to end up with the fastest possible clip.
//
// XXX Antialiasing will fail pretty hard here, since we can't clip with AA
// with QPainter.
qs->p->save();
qs->no_update_clip_bounds = true;
status = _cairo_qpainter_surface_intersect_clip_path (qs, path, fill_rule, tolerance, antialias);
qs->no_update_clip_bounds = 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);
@ -1179,13 +1209,14 @@ _cairo_qpainter_surface_fill (void *abstract_surface,
qs->p->drawPixmap (0, 0, *qsSrc->pixmap);
}
qs->p->setWorldMatrix (savedMatrix, false);
qs->p->restore();
} 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);
qs->p->fillPath (qpath, brush);
}
if (qs->supports_porter_duff)