? TODO ? cairomm_refptr.patch ? cairomm_refptr_jmj.patch ? releases ? examples/path-iter ? examples/pdf-surface/image.pdf ? examples/png_file/image.png ? examples/ps-surface/image.ps ? examples/svg-surface/image.svg Index: cairomm/context.cc =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/context.cc,v retrieving revision 1.13 diff -u -5 -p -r1.13 context.cc --- cairomm/context.cc 23 Jun 2006 18:37:44 -0000 1.13 +++ cairomm/context.cc 9 Jul 2006 21:36:06 -0000 @@ -47,21 +47,10 @@ Context::~Context() { if(m_cobject) cairo_destroy(m_cobject); } - -void Context::reference() const -{ - cairo_reference(m_cobject); -} - -void Context::unreference() const -{ - cairo_destroy(m_cobject); -} - void Context::save() { cairo_save(m_cobject); check_object_status_and_throw_exception(*this); } Index: cairomm/context.h =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/context.h,v retrieving revision 1.17 diff -u -5 -p -r1.17 context.h --- cairomm/context.h 5 Jul 2006 15:37:12 -0000 1.17 +++ cairomm/context.h 9 Jul 2006 21:36:07 -0000 @@ -913,12 +913,10 @@ public: #ifndef DOXYGEN_IGNORE_THIS ///For use only by the cairomm implementation. inline ErrorStatus get_status() const { return cairo_status(const_cast(cobj())); } - void reference() const; - void unreference() const; #endif //DOXYGEN_IGNORE_THIS protected: Index: cairomm/fontface.cc =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/fontface.cc,v retrieving revision 1.8 diff -u -5 -p -r1.8 fontface.cc --- cairomm/fontface.cc 28 Jun 2006 00:26:10 -0000 1.8 +++ cairomm/fontface.cc 9 Jul 2006 21:36:07 -0000 @@ -35,20 +35,10 @@ FontFace::~FontFace() { if(m_cobject) cairo_font_face_destroy(m_cobject); } -void FontFace::reference() const -{ - cairo_font_face_reference(m_cobject); -} - -void FontFace::unreference() const -{ - cairo_font_face_destroy(m_cobject); -} - /* void* FontFace::get_user_data(const cairo_user_data_key_t *key) { void* result = cairo_font_face_get_user_data(m_cobject, key); check_object_status_and_throw_exception(*this); Index: cairomm/fontface.h =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/fontface.h,v retrieving revision 1.10 diff -u -5 -p -r1.10 fontface.h --- cairomm/fontface.h 5 Jul 2006 15:37:12 -0000 1.10 +++ cairomm/fontface.h 9 Jul 2006 21:36:07 -0000 @@ -62,13 +62,10 @@ public: ///For use only by the cairomm implementation. inline ErrorStatus get_status() const { return cairo_font_face_status(const_cast(cobj())); } #endif //DOXYGEN_IGNORE_THIS - void reference() const; - void unreference() const; - protected: cobject* m_cobject; }; Index: cairomm/pattern.cc =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/pattern.cc,v retrieving revision 1.8 diff -u -5 -p -r1.8 pattern.cc --- cairomm/pattern.cc 28 Jun 2006 00:26:10 -0000 1.8 +++ cairomm/pattern.cc 9 Jul 2006 21:36:07 -0000 @@ -40,20 +40,10 @@ Pattern::~Pattern() { if(m_cobject) cairo_pattern_destroy(m_cobject); } -void Pattern::reference() const -{ - cairo_pattern_reference(m_cobject); -} - -void Pattern::unreference() const -{ - cairo_pattern_destroy(m_cobject); -} - void Pattern::set_matrix(const cairo_matrix_t &matrix) { cairo_pattern_set_matrix(m_cobject, &matrix); check_object_status_and_throw_exception(*this); } Index: cairomm/pattern.h =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/pattern.h,v retrieving revision 1.11 diff -u -5 -p -r1.11 pattern.h --- cairomm/pattern.h 5 Jul 2006 15:37:12 -0000 1.11 +++ cairomm/pattern.h 9 Jul 2006 21:36:07 -0000 @@ -59,13 +59,10 @@ public: ///For use only by the cairomm implementation. inline ErrorStatus get_status() const { return cairo_pattern_status(const_cast(cobj())); } #endif //DOXYGEN_IGNORE_THIS - void reference() const; - void unreference() const; - protected: //Used by derived types only. Pattern(); cobject* m_cobject; Index: cairomm/refptr.h =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/refptr.h,v retrieving revision 1.3 diff -u -5 -p -r1.3 refptr.h --- cairomm/refptr.h 6 Mar 2006 17:55:51 -0000 1.3 +++ cairomm/refptr.h 9 Jul 2006 21:36:07 -0000 @@ -26,11 +26,11 @@ namespace Cairo { /** RefPtr<> is a reference-counting shared smartpointer. * - * Some objects in gtkmm are obtained from a shared + * Some objects in cairomm are obtained from a shared * store. Consequently you cannot instantiate them yourself. Instead they * return a RefPtr which behaves much like an ordinary pointer in that members * can be reached with the usual object_ptr->member notation. * Unlike most other smart pointers, RefPtr doesn't support dereferencing * through *object_ptr. @@ -38,12 +38,10 @@ namespace Cairo * Reference counting means that a shared reference count is incremented each * time a RefPtr is copied, and decremented each time a RefPtr is destroyed, * for instance when it leaves its scope. When the reference count reaches * zero, the contained object is deleted, meaning you don't need to remember * to delete the object. - * - * RefPtr<> can store any class that has reference() and unreference() methods. */ template class RefPtr { public: @@ -54,11 +52,13 @@ public: inline RefPtr(); /// Destructor - decrements reference count. inline ~RefPtr(); - /// For use only by the ::create() methods. + /** For use only by the ::create() methods. + * This assumes that @a pCppObject already has a starting reference. + */ explicit inline RefPtr(T_CppObject* pCppObject); /** Copy constructor * * This increments the shared reference count. @@ -144,16 +144,28 @@ public: * @endcode */ template static inline RefPtr cast_const(const RefPtr& src); + +#ifndef DOXYGEN_IGNORE_THIS + + // Warning: This is for internal use only. Do not manually modify the + // reference count with this pointer + inline int* refcount() { return pCppRefcount_; } + +#endif // DOXYGEN_IGNORE_THIS + private: + void unref(); + T_CppObject* pCppObject_; + int* pCppRefcount_; }; -#ifndef DOXYGEN_SHOULD_SKIP_THIS +#ifndef DOXYGEN_IGNORE_THIS // RefPtr<>::operator->() comes first here since it's used by other methods. // If it would come after them it wouldn't be inlined. template inline @@ -163,33 +175,62 @@ T_CppObject* RefPtr::operat } template inline RefPtr::RefPtr() : - pCppObject_ (0) + pCppObject_(0), + pCppRefcount_(0) {} template inline RefPtr::~RefPtr() { - if(pCppObject_) - pCppObject_->unreference(); // This could cause pCppObject to be deleted. + unref(); } template inline +void RefPtr::unref() +{ + if(pCppRefcount_) + { + --(*pCppRefcount_); + + if(*pCppRefcount_ == 0) + { + if(pCppObject_) + { + delete pCppObject_; + pCppObject_ = 0; + } + } + + delete pCppRefcount_; + pCppRefcount_ = 0; + } +} + + +template inline RefPtr::RefPtr(T_CppObject* pCppObject) : - pCppObject_ (pCppObject) -{} + pCppObject_(pCppObject) +{ + if(pCppObject) + { + pCppRefcount_ = new int; + *pCppRefcount_ = 1; //This will be decremented in the destructor. + } +} template inline RefPtr::RefPtr(const RefPtr& src) : - pCppObject_ (src.pCppObject_) + pCppObject_ (src.pCppObject_), + pCppRefcount_(src.pCppRefcount_) { - if(pCppObject_) - pCppObject_->reference(); + if(pCppObject_ && pCppRefcount_) + ++(*pCppRefcount_); } // The templated ctor allows copy construction from any object that's // castable. Thus, it does downcasts: // base_ref = derived_ref @@ -199,22 +240,28 @@ inline RefPtr::RefPtr(const RefPtr& src) : // A different RefPtr<> will not allow us access to pCppObject_. We need // to add a get_underlying() for this, but that would encourage incorrect // use, so we use the less well-known operator->() accessor: - pCppObject_ (src.operator->()) + pCppObject_ (src.operator->()), + pCppRefcount_(refcount()) { - if(pCppObject_) - pCppObject_->reference(); + if(pCppObject_ && pCppRefcount_) + ++(*pCppRefcount_); } template inline void RefPtr::swap(RefPtr& other) { T_CppObject *const temp = pCppObject_; + int* temp_count = pCppRefcount_; + pCppObject_ = other.pCppObject_; + pCppRefcount_ = other.pCppRefcount_; + other.pCppObject_ = temp; + other.pCppRefcount_ = temp_count; } template inline RefPtr& RefPtr::operator=(const RefPtr& src) { @@ -287,43 +334,43 @@ template inline RefPtr RefPtr::cast_dynamic(const RefPtr& src) { T_CppObject *const pCppObject = dynamic_cast(src.operator->()); - if(pCppObject) - pCppObject->reference(); + if(pCppObject && src.pCppRefcount_) + ++(*(src.pCppRefcount_)); - return RefPtr(pCppObject); + return RefPtr(pCppObject); //TODO: Does an unnecessary extra reference() on the C object. } template template inline RefPtr RefPtr::cast_static(const RefPtr& src) { T_CppObject *const pCppObject = static_cast(src.operator->()); - if(pCppObject) - pCppObject->reference(); + if(pCppObject && src.pCppRefcount_) + ++(*(src.pCppRefcount_)); - return RefPtr(pCppObject); + return RefPtr(pCppObject); //TODO: Does an unnecessary extra reference() on the C object. } template template inline RefPtr RefPtr::cast_const(const RefPtr& src) { T_CppObject *const pCppObject = const_cast(src.operator->()); - if(pCppObject) - pCppObject->reference(); + if(pCppObject && src.pCppRefcount_) + ++(*(src.pCppRefcount_)); - return RefPtr(pCppObject); + return RefPtr(pCppObject); //TODO: Does an unnecessary extra reference() on the C object. } -#endif /* DOXYGEN_SHOULD_SKIP_THIS */ +#endif /* DOXYGEN_IGNORE_THIS */ /** @relates Glib::RefPtr */ template inline void swap(RefPtr& lhs, RefPtr& rhs) { Index: cairomm/scaledfont.h =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/scaledfont.h,v retrieving revision 1.3 diff -u -5 -p -r1.3 scaledfont.h --- cairomm/scaledfont.h 5 Jul 2006 15:17:21 -0000 1.3 +++ cairomm/scaledfont.h 9 Jul 2006 21:36:07 -0000 @@ -49,13 +49,10 @@ public: #ifndef DOXYGEN_IGNORE_THIS // For use only by the cairomm implementation. inline ErrorStatus get_status() const { return cairo_scaled_font_status(const_cast(cobj())); } - // for RefPtr - void reference() const { cairo_scaled_font_reference(m_cobject); } - void unreference() const { cairo_scaled_font_destroy(m_cobject); } #endif //DOXYGEN_IGNORE_THIS /** Createa C++ wrapper object from the C instance. This C++ object should * then be given to a RefPtr. */ Index: cairomm/surface.cc =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/surface.cc,v retrieving revision 1.18 diff -u -5 -p -r1.18 surface.cc --- cairomm/surface.cc 5 Jul 2006 15:37:12 -0000 1.18 +++ cairomm/surface.cc 9 Jul 2006 21:36:07 -0000 @@ -106,20 +106,10 @@ void Surface::write_to_png(cairo_write_f ErrorStatus status = cairo_surface_write_to_png_stream(m_cobject, write_func, closure); check_status_and_throw_exception(status); } #endif -void Surface::reference() const -{ - cairo_surface_reference(m_cobject); -} - -void Surface::unreference() const -{ - cairo_surface_destroy(m_cobject); -} - RefPtr Surface::create(const RefPtr other, Content content, int width, int height) { cairo_surface_t* cobject = cairo_surface_create_similar(other->m_cobject, (cairo_content_t)content, width, height); check_status_and_throw_exception(cairo_surface_status(cobject)); return RefPtr(new Surface(cobject, true /* has reference */)); Index: cairomm/surface.h =================================================================== RCS file: /cvs/cairo/cairomm/cairomm/surface.h,v retrieving revision 1.18 diff -u -5 -p -r1.18 surface.h --- cairomm/surface.h 5 Jul 2006 15:37:12 -0000 1.18 +++ cairomm/surface.h 9 Jul 2006 21:36:07 -0000 @@ -188,12 +188,10 @@ public: #ifndef DOXYGEN_IGNORE_THIS ///For use only by the cairomm implementation. inline ErrorStatus get_status() const { return cairo_surface_status(const_cast(cobj())); } - void reference() const; - void unreference() const; #endif //DOXYGEN_IGNORE_THIS /** Create a new surface that is as compatible as possible with an existing * surface. The new surface will use the same backend as other unless that is * not possible for some reason.