From 568a080944ccbc3df0a6c7c38866268fd8b9f5a3 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 13 Feb 2014 02:10:10 +0200 Subject: [PATCH 6/7] Wrap new Surface member functions --- cairomm/surface.cc | 47 +++++++++++++++++++++++++++++++++ cairomm/surface.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/cairomm/surface.cc b/cairomm/surface.cc index e1b517e..c53a2ef 100644 --- a/cairomm/surface.cc +++ b/cairomm/surface.cc @@ -296,6 +296,53 @@ RefPtr Surface::create(const RefPtr& target, double x, double return RefPtr(new Surface(cobject, true /* has reference */)); } +RefPtr Surface::create_similar_image(Format format, int width, + int height) +{ + cairo_surface_t* surf = + cairo_surface_create_similar_image(m_cobject, static_cast(format), + width, height); + check_status_and_throw_exception(cairo_surface_status(surf)); + return RefPtr(new Surface(surf, true /* has reference */)); +} + +bool Surface::supports_mime_type(const std::string& mime_type) +{ + return cairo_surface_supports_mime_type(m_cobject, mime_type.c_str()); +} + +Surface::MappedImagePtr Surface::map_to_image(const RectangleInt& extents) +{ + cairo_surface_t* surf = cairo_surface_map_to_image(m_cobject, &extents); + check_status_and_throw_exception(cairo_surface_status(surf)); + return MappedImagePtr(new Surface(surf, true /* has reference */), this); +} + +Surface::MappedImagePtr Surface::map_to_image() +{ + cairo_surface_t* surf = cairo_surface_map_to_image(m_cobject, NULL); + check_status_and_throw_exception(cairo_surface_status(surf)); + return MappedImagePtr(new Surface(surf, true /* has reference */), this); +} + +void Surface::unmap_image(MappedImagePtr& image) +{ + cairo_surface_unmap_image(m_cobject, image.surf_->cobj()); + delete image.surf_; + image.surf_ = NULL; + check_status_and_throw_exception(cairo_surface_status(m_cobject)); +} + +Surface::MappedImagePtr::~MappedImagePtr() +{ + try { + if (surf_) { + parent_->unmap_image(*this); + } + } catch (...) { + // ignore + } +} ImageSurface::ImageSurface(cairo_surface_t* cobject, bool has_reference) : Surface(cobject, has_reference) diff --git a/cairomm/surface.h b/cairomm/surface.h index 379742d..91fb7cb 100644 --- a/cairomm/surface.h +++ b/cairomm/surface.h @@ -347,6 +347,82 @@ public: #endif // CAIRO_HAS_PNG_FUNCTIONS + /** + * Create a new image surface that is as compatible as possible for uploading + * to and the use in conjunction with an existing surface. However, this + * surface can still be used like any normal image surface. + * + * Initially the surface contents are all 0 (transparent if contents have + * transparency, black otherwise.) + * + * Use Surface::create_similar() if you don't need an image surface. + * + * Throws an exception on error. + * + * @param format the format for the new surface + * @param width width of the new surface, (in device-space units) + * @param height height of the new surface (in device-space units) + * + * @since 1.12 + */ + RefPtr create_similar_image(Format format, int width, int height); + + /** + * Checks whether @a mime_type is supported by the surface + * + * @param mime_type the mime type + * @since 1.12 + */ + bool supports_mime_type(const std::string& mime_type); + + // FIXME: think about a proper name + class MappedImagePtr { + public: + ~MappedImagePtr(); + + Surface* operator->() { return surf_; } + private: + friend class Surface; + MappedImagePtr(Surface* surf, Surface* parent) : surf_(surf), parent_(parent) {} + void unmap(); + + Surface* surf_; + Surface* parent_; + }; + + /// @{ + /** + * Returns an image surface that is the most efficient mechanism for + * modifying the backing store of the target surface. The region retrieved + * may be limited to the extents or the whole surface. + * + * @note The use of the original surface as a target or source whilst it is + * mapped is undefined. The result of mapping the surface multiple times is + * undefined. Destroying the surface or calling Surface::finish() results in + * undefined behavior. Changing the device transform of the image surface or + * of surface before the image surface is unmapped results in undefined + * behavior. + * + * @param extents limit the extraction to an rectangular region + * @since 1.12 + */ + MappedImagePtr map_to_image(const RectangleInt& extents); + MappedImagePtr map_to_image(); + /// @} + + /** + * Unmaps the image surface as returned from map_to_image(). + * + * The content of the image will be uploaded to the target surface. + * Afterwards, the image is destroyed. + * + * Using an image surface which wasn't returned by map_to_image() results in + * undefined behavior. + * + * @since 1.12 + */ + void unmap_image(MappedImagePtr& image); + /** This function returns the device for a surface * @return The device for this surface, or an empty RefPtr if the surface has * no associated device */ -- 1.8.5.3