static void _cairo_qt_surface_set_clip_region (cairo_qt_surface_t *qs, const cairo_region_t *clip_region) { _cairo_surface_clipper_reset (&qs->clipper); if (clip_region == NULL) { // How the clip path is reset depends on whether we own p or not if (qs->pixmap || qs->image) { // we own p qs->p->setClipping (false); } else { qs->p->restore (); qs->p->save (); } } else { QRegion qr; int num_rects = cairo_region_num_rectangles (clip_region); for (int i = 0; i < num_rects; ++i) { cairo_rectangle_int_t rect; cairo_region_get_rectangle (clip_region, i, &rect); QRect r(rect.x, rect.y, rect.width, rect.height); qr = qr.unite(r); } qs->p->setClipRegion (qr, Qt::IntersectClip); } }
static cairo_status_t _cairo_qt_surface_finish (void *abstract_surface) { cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; D(fprintf(stderr, "q[%p] finish\n", abstract_surface)); /* Only delete p if we created it */ if (qs->image || qs->pixmap) delete qs->p; else qs->p->restore (); if (qs->image_equiv) cairo_surface_destroy (qs->image_equiv); _cairo_surface_clipper_reset (&qs->clipper); if (qs->image) delete qs->image; if (qs->pixmap) delete qs->pixmap; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _cairo_skia_surface_finish (void *asurface) { cairo_skia_surface_t *surface = (cairo_skia_surface_t *) asurface; _cairo_surface_clipper_reset (&surface->clipper); cairo_surface_destroy (&surface->_image_surface->base); delete surface->canvas; delete surface->bitmap; return CAIRO_STATUS_SUCCESS; }
static cairo_int_status_t _cairo_qt_surface_set_clip (cairo_qt_surface_t *qs, const cairo_clip_t *clip) { cairo_int_status_t status; D(fprintf(stderr, "q[%p] intersect_clip_path %s\n", abstract_surface, path ? "(path)" : "(clear)")); if (clip == NULL) { _cairo_surface_clipper_reset (&qs->clipper); // How the clip path is reset depends on whether we own p or not if (qs->pixmap || qs->image) { // we own p qs->p->setClipping (false); } else { qs->p->restore (); qs->p->save (); } return CAIRO_INT_STATUS_SUCCESS; } #if ENABLE_FAST_CLIP // Qt will implicitly enable clipping, and will use ReplaceClip // instead of IntersectClip if clipping was disabled before // Note: Qt is really bad at dealing with clip paths. It doesn't // seem to usefully recognize rectangular paths, instead going down // extremely slow paths whenever a clip path is set. So, // we do a bunch of work here to try to get rectangles or regions // down to Qt for clipping. cairo_region_t *clip_region = NULL; status = _cairo_clip_get_region (clip, &clip_region); if (status == CAIRO_INT_STATUS_UNSUPPORTED) { // We weren't able to extract a region from the traps. // Just hand the path down to QPainter. status = (cairo_int_status_t) _cairo_surface_clipper_set_clip (&qs->clipper, clip); } else if (status == CAIRO_INT_STATUS_SUCCESS) { _cairo_qt_surface_set_clip_region (qs, clip_region); status = CAIRO_INT_STATUS_SUCCESS; } #else status = (cairo_int_status_t) _cairo_surface_clipper_set_clip (&qs->clipper, clip); #endif return status; }