summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathon Jongsma <jonathon.jongsma@collabora.co.uk>2008-08-15 00:37:45 -0500
committerJonathon Jongsma <jonathon.jongsma@collabora.co.uk>2008-08-18 20:58:27 -0500
commitc6efb90e89953cf25b835a7bb844404a65adcbcb (patch)
treea91f45d05871e3b49773940d42d6ff059374e032
parenta98b16b1785685cff8541bc0c3ced5390f652ab1 (diff)
Add UserFontFace API
-rw-r--r--ChangeLog14
-rw-r--r--cairomm/context.h2
-rw-r--r--cairomm/enums.h3
-rw-r--r--cairomm/fontface.cc194
-rw-r--r--cairomm/fontface.h67
-rw-r--r--configure.in4
-rw-r--r--tests/test-font-face.cc202
7 files changed, 481 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 627a7ee..0ba61e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2008-08-14 Jonathon Jongsma <jjongsma@gnome.org>
+
+ * cairomm/context.h: move some text-related typedefs into the fontface
+ header since they're needed for new user font API and that's really where they
+ should be owned. context.h includes fontface.h, so there should not be any
+ breakage for people who were just including context.h
+ * cairomm/enums.h: add user font type to font type enum
+ * cairomm/fontface.cc:
+ * cairomm/fontface.h: add UserFontFace class. This class has a set of
+ callbacks that can be used to do certain things. In order to do this in a
+ flexible way, I have added libsigc++ as a dependency of cairo to achieve this
+ * configure.in: add check for libsigc++
+ * tests/test-font-face.cc: add tests for UserFontFace
+
2008-08-15 Jonathon Jongsma <jjongsma@gnome.org>
* cairomm/scaledfont.h:
diff --git a/cairomm/context.h b/cairomm/context.h
index 711309e..2371152 100644
--- a/cairomm/context.h
+++ b/cairomm/context.h
@@ -34,8 +34,6 @@ namespace Cairo
{
typedef cairo_glyph_t Glyph; //A simple struct.
-typedef cairo_font_extents_t FontExtents; //A simple struct.
-typedef cairo_text_extents_t TextExtents; //A simple struct.
typedef cairo_matrix_t Matrix; //A simple struct. //TODO: Derive and add operator[] and operator. matrix multiplication?
typedef cairo_rectangle_t Rectangle;
diff --git a/cairomm/enums.h b/cairomm/enums.h
index 8f4cb39..062f932 100644
--- a/cairomm/enums.h
+++ b/cairomm/enums.h
@@ -193,7 +193,8 @@ typedef enum
FONT_TYPE_FT = CAIRO_FONT_TYPE_FT,
FONT_TYPE_WIN32 = CAIRO_FONT_TYPE_WIN32,
FONT_TYPE_ATSUI = CAIRO_FONT_TYPE_QUARTZ, /**< @deprecated Use FONT_TYPE_QUARTZ instead. */
- FONT_TYPE_QUARTZ = CAIRO_FONT_TYPE_QUARTZ
+ FONT_TYPE_QUARTZ = CAIRO_FONT_TYPE_QUARTZ,
+ FONT_TYPE_USER = CAIRO_FONT_TYPE_USER
} FontType;
} // namespace Cairo
diff --git a/cairomm/fontface.cc b/cairomm/fontface.cc
index f7cf8cd..338f299 100644
--- a/cairomm/fontface.cc
+++ b/cairomm/fontface.cc
@@ -16,7 +16,9 @@
* 02110-1301, USA.
*/
+#include <iostream>
#include <cairomm/fontface.h>
+#include <cairomm/scaledfont.h>
#include <cairomm/private.h>
namespace Cairo
@@ -101,6 +103,198 @@ FontWeight ToyFontFace::get_weight() const
}
+//*************************//
+// UserFont Implementation //
+//*************************//
+struct UserFontFace::PrivateData
+{
+ SlotInit* m_init_slot;
+ SlotUnicodeToGlyph* m_unicode_to_glyph_slot;
+ SlotRenderGlyph* m_render_glyph_slot;
+
+ PrivateData()
+ : m_init_slot (0)
+ , m_unicode_to_glyph_slot (0)
+ , m_render_glyph_slot (0)
+ {
+ }
+
+ ~PrivateData()
+ {
+ if (m_init_slot)
+ delete m_init_slot;
+ if (m_unicode_to_glyph_slot)
+ delete m_unicode_to_glyph_slot;
+ if (m_render_glyph_slot)
+ delete m_render_glyph_slot;
+ }
+};
+
+static const cairo_user_data_key_t user_font_key = {0};
+
+static void
+log_uncaught_exception(const char* message = 0)
+{
+ std::cerr << "*** cairomm: Uncaught exception in slot callback";
+ if (message)
+ std::cerr << ": " << message;
+ std::cerr << std::endl;
+}
+
+cairo_status_t
+UserFontFace::init_cb (cairo_scaled_font_t* scaled_font,
+ cairo_t *cr,
+ cairo_font_extents_t* metrics)
+{
+ cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaled_font);
+ // we've stored a pointer to the wrapper object in the C object's user_data
+ UserFontFace* instance =
+ static_cast<UserFontFace*>(cairo_font_face_get_user_data(face,
+ &user_font_key));
+ if (instance && instance->m_priv && instance->m_priv->m_init_slot) {
+ try {
+ return (*instance->m_priv->m_init_slot)(RefPtr<ScaledFont>(new ScaledFont(scaled_font)),
+ RefPtr<Context>(new Context(cr)),
+ static_cast<FontExtents&>(*metrics));
+ } catch (const std::exception& ex) {
+ log_uncaught_exception(ex.what());
+ } catch ( ... ) {
+ log_uncaught_exception();
+ }
+ }
+ // this should never happen
+ return CAIRO_STATUS_USER_FONT_ERROR;
+}
+
+cairo_status_t
+UserFontFace::unicode_to_glyph_cb (cairo_scaled_font_t *scaled_font,
+ unsigned long unicode,
+ unsigned long *glyph)
+{
+ cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaled_font);
+ // we've stored a pointer to the wrapper object in the C object's user_data
+ UserFontFace* instance =
+ static_cast<UserFontFace*>(cairo_font_face_get_user_data(face,
+ &user_font_key));
+ if (instance && instance->m_priv && instance->m_priv->m_unicode_to_glyph_slot) {
+ try {
+ return (*instance->m_priv->m_unicode_to_glyph_slot)(RefPtr<ScaledFont>(new ScaledFont(scaled_font)),
+ unicode, *glyph);
+ } catch (const std::exception& ex) {
+ log_uncaught_exception(ex.what());
+ } catch ( ... ) {
+ log_uncaught_exception();
+ }
+ }
+ // this should never happen
+ return CAIRO_STATUS_USER_FONT_ERROR;
+}
+
+cairo_status_t
+UserFontFace::render_glyph_cb (cairo_scaled_font_t *scaled_font,
+ unsigned long glyph,
+ cairo_t *cr,
+ cairo_text_extents_t *metrics)
+{
+ cairo_font_face_t* face = cairo_scaled_font_get_font_face(scaled_font);
+ // we've stored a pointer to the wrapper object in the C object's user_data
+ UserFontFace* instance =
+ static_cast<UserFontFace*>(cairo_font_face_get_user_data(face,
+ &user_font_key));
+ if (instance && instance->m_priv && instance->m_priv->m_render_glyph_slot) {
+ try {
+ return (*instance->m_priv->m_render_glyph_slot)(RefPtr<ScaledFont>(new ScaledFont(scaled_font)),
+ glyph, RefPtr<Context>(new Context(cr)),
+ static_cast<TextExtents&>(*metrics));
+ } catch (const std::exception& ex) {
+ log_uncaught_exception(ex.what());
+ } catch ( ... ) {
+ log_uncaught_exception();
+ }
+ }
+ // this should never happen
+ return CAIRO_STATUS_USER_FONT_ERROR;
+}
+
+RefPtr<UserFontFace> UserFontFace::create()
+{
+ return RefPtr<UserFontFace>(new UserFontFace());
+}
+
+UserFontFace::UserFontFace()
+ : FontFace(cairo_user_font_face_create(), true /* has reference */)
+ , m_priv(new PrivateData())
+{
+ check_status_and_throw_exception(cairo_font_face_status(m_cobject));
+
+ // store a pointer to the wrapper class in the user-data, so that when one of
+ // the callback functions gets called (which has to be a plain-C function so
+ // can't be a class member), we can get a reference to the wrapper class
+ cairo_font_face_set_user_data (m_cobject, &user_font_key,
+ (void*)this, (cairo_destroy_func_t) NULL);
+}
+
+UserFontFace::~UserFontFace()
+{
+ delete m_priv;
+}
+
+void UserFontFace::set_init_func(const SlotInit& init_func)
+{
+ if (!m_priv)
+ return;
+ if (m_priv->m_init_slot)
+ delete m_priv->m_init_slot;
+ // copy the new slot
+ m_priv->m_init_slot = new SlotInit(init_func);
+
+ // register it with cairo
+ cairo_user_font_face_set_init_func (cobj(), init_cb);
+}
+
+void UserFontFace::set_render_glyph_func(const SlotRenderGlyph& render_glyph_func)
+{
+ if (!m_priv)
+ return;
+ if (m_priv->m_render_glyph_slot)
+ delete m_priv->m_render_glyph_slot;
+ // copy the slot
+ m_priv->m_render_glyph_slot = new SlotRenderGlyph(render_glyph_func);
+ cairo_user_font_face_set_render_glyph_func (cobj(), render_glyph_cb);
+}
+
+void UserFontFace::set_unicode_to_glyph_func(const SlotUnicodeToGlyph& unicode_to_glyph_func)
+{
+ if (!m_priv)
+ return;
+ if (m_priv->m_unicode_to_glyph_slot)
+ delete m_priv->m_unicode_to_glyph_slot;
+ // copy the slot
+ m_priv->m_unicode_to_glyph_slot = new SlotUnicodeToGlyph(unicode_to_glyph_func);
+ cairo_user_font_face_set_unicode_to_glyph_func (cobj(), unicode_to_glyph_cb);
+}
+
+const UserFontFace::SlotInit* UserFontFace::get_init_func() const
+{
+ if (!m_priv)
+ return 0;
+ return m_priv->m_init_slot;
+}
+
+const UserFontFace::SlotRenderGlyph* UserFontFace::get_render_glyph_func() const
+{
+ if (!m_priv)
+ return 0;
+ return m_priv->m_render_glyph_slot;
+}
+
+const UserFontFace::SlotUnicodeToGlyph* UserFontFace::get_unicode_to_glyph_func() const
+{
+ if (!m_priv)
+ return 0;
+ return m_priv->m_unicode_to_glyph_slot;
+}
+
} //namespace Cairo
// vim: ts=2 sw=2 et
diff --git a/cairomm/fontface.h b/cairomm/fontface.h
index ed6da61..c107eb5 100644
--- a/cairomm/fontface.h
+++ b/cairomm/fontface.h
@@ -22,12 +22,18 @@
#include <string>
#include <cairomm/enums.h>
#include <cairomm/refptr.h>
+#include <sigc++/slot.h>
#include <cairo.h>
namespace Cairo
{
+class ScaledFont;
+class Context;
+typedef cairo_font_extents_t FontExtents; //A simple struct.
+typedef cairo_text_extents_t TextExtents; //A simple struct.
+
/**
* This is a reference-counted object that should be used via Cairo::RefPtr.
*/
@@ -38,7 +44,6 @@ protected:
//TODO?: FontFace(cairo_font_face_t *target);
public:
-
/** Create a C++ wrapper for the C instance. This C++ instance should then be given to a RefPtr.
* @param cobject The C instance.
* @param has_reference Whether we already have a reference. Otherwise, the constructor will take an extra reference.
@@ -87,6 +92,66 @@ protected:
ToyFontFace(const std::string& family, FontSlant slant, FontWeight weight);
};
+
+class UserFontFace : public FontFace
+{
+public:
+ static RefPtr<UserFontFace> create();
+
+ typedef sigc::slot<ErrorStatus,
+ const RefPtr<ScaledFont>&,
+ const RefPtr<Context>&,
+ FontExtents&> SlotInit;
+ typedef sigc::slot<ErrorStatus,
+ const RefPtr<ScaledFont>&,
+ unsigned long /*unicode*/,
+ unsigned long& /*glyph*/> SlotUnicodeToGlyph;
+ typedef sigc::slot<ErrorStatus,
+ const RefPtr<ScaledFont>&,
+ unsigned long /*glyph*/,
+ const RefPtr<Context>&,
+ TextExtents& /*metrics*/> SlotRenderGlyph;
+ // FIXME: add SlotTextToGlyphs
+
+ void set_init_func(const SlotInit& init_func);
+ void set_render_glyph_func(const SlotRenderGlyph& render_glyph_func);
+ void set_unicode_to_glyph_func(const SlotUnicodeToGlyph& unicode_to_glyph_func);
+ // FIXME: add set_text_to_glyphs_func
+
+ // FIXME: are these really useful? What would you do with a sigc::slot when
+ // you got it?
+ const SlotInit* get_init_func() const;
+ const SlotRenderGlyph* get_render_glyph_func() const;
+ const SlotUnicodeToGlyph* get_unicode_to_glyph_func() const;
+ // FIXME: add get_text_to_glyphs_func
+
+
+ virtual ~UserFontFace();
+
+protected:
+ UserFontFace();
+
+private:
+ struct PrivateData;
+ PrivateData* m_priv;
+
+static cairo_status_t
+init_cb(cairo_scaled_font_t* scaled_font,
+ cairo_t *cr,
+ cairo_font_extents_t* metrics);
+
+static cairo_status_t
+unicode_to_glyph_cb(cairo_scaled_font_t *scaled_font,
+ unsigned long unicode,
+ unsigned long *glyph);
+
+static cairo_status_t
+render_glyph_cb(cairo_scaled_font_t *scaled_font,
+ unsigned long glyph,
+ cairo_t *cr,
+ cairo_text_extents_t *metrics);
+};
+
} // namespace Cairo
#endif //__CAIROMM_FONTFACE_H
diff --git a/configure.in b/configure.in
index 6392656..b2daf17 100644
--- a/configure.in
+++ b/configure.in
@@ -105,7 +105,9 @@ dnl some platforms (e.g. Solaris) need additional C headers included so
dnl that there are always prototypes and defines available.
AC_CHECK_HEADERS(math.h)
-PKG_CHECK_MODULES(CAIROMM, cairo >= 1.5.10)
+PKG_CHECK_MODULES(CAIROMM,
+ cairo >= 1.6.0
+ sigc++-2.0)
AC_ARG_ENABLE(tests,
AC_HELP_STRING([--enable-tests=yes|no],
diff --git a/tests/test-font-face.cc b/tests/test-font-face.cc
index 973f956..fe7f5f0 100644
--- a/tests/test-font-face.cc
+++ b/tests/test-font-face.cc
@@ -7,11 +7,15 @@
*/
#include <cfloat>
+#include <stdexcept>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/floating_point_comparison.hpp>
using namespace boost::unit_test;
#include <cairomm/fontface.h>
+#include <cairomm/scaledfont.h>
+
+static Cairo::Matrix identity_matrix;
void
test_create_toy ()
@@ -36,6 +40,196 @@ void test_toy_getters ()
BOOST_CHECK_EQUAL (Cairo::FONT_TYPE_TOY, toy->get_type());
}
+void test_user_font_create()
+{
+ Cairo::RefPtr<Cairo::UserFontFace> font = Cairo::UserFontFace::create();
+ BOOST_CHECK_EQUAL (Cairo::FONT_TYPE_USER, font->get_type());
+}
+
+// create some dummy callbacks
+static unsigned int init_call_count = 0;
+Cairo::ErrorStatus my_init(const Cairo::RefPtr<Cairo::ScaledFont>&, const Cairo::RefPtr<Cairo::Context>&, Cairo::FontExtents&)
+{
+ init_call_count++;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static unsigned int unicode_to_glyph_call_count = 0;
+Cairo::ErrorStatus my_unicode_to_glyph(const Cairo::RefPtr<Cairo::ScaledFont>&, unsigned long, unsigned long&)
+{
+ unicode_to_glyph_call_count++;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static unsigned int render_glyph_call_count = 0;
+Cairo::ErrorStatus my_render_glyph(const Cairo::RefPtr<Cairo::ScaledFont>&, unsigned long, const Cairo::RefPtr<Cairo::Context>&, Cairo::TextExtents&)
+{
+ render_glyph_call_count++;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+void test_user_font_callbacks_ptr()
+{
+ Cairo::RefPtr<Cairo::UserFontFace> font = Cairo::UserFontFace::create();
+ BOOST_CHECK(font);
+ font->set_init_func(sigc::ptr_fun(my_init));
+ font->set_unicode_to_glyph_func(sigc::ptr_fun(my_unicode_to_glyph));
+ font->set_render_glyph_func(sigc::ptr_fun(my_render_glyph));
+ Cairo::RefPtr<Cairo::ScaledFont> scaled_font =
+ Cairo::ScaledFont::create(font, identity_matrix, identity_matrix,
+ Cairo::FontOptions());
+ BOOST_CHECK (init_call_count > 0);
+ Cairo::RefPtr<Cairo::ImageSurface> surface =
+ Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 100, 100);
+ Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
+ cr->set_font_face(font);
+ cr->show_text("Hello, world");
+ BOOST_CHECK (unicode_to_glyph_call_count > 0);
+ BOOST_CHECK (render_glyph_call_count > 0);
+}
+
+struct UserFontCallbacks
+{
+Cairo::ErrorStatus init(const Cairo::RefPtr<Cairo::ScaledFont>&, const Cairo::RefPtr<Cairo::Context>&, Cairo::FontExtents&)
+{
+ init_call_count++;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+Cairo::ErrorStatus unicode_to_glyph(const Cairo::RefPtr<Cairo::ScaledFont>&, unsigned long, unsigned long&)
+{
+ unicode_to_glyph_call_count++;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+Cairo::ErrorStatus render_glyph(const Cairo::RefPtr<Cairo::ScaledFont>&, unsigned long, const Cairo::RefPtr<Cairo::Context>&, Cairo::TextExtents&)
+{
+ render_glyph_call_count++;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static unsigned int init_call_count;
+static unsigned int unicode_to_glyph_call_count;
+static unsigned int render_glyph_call_count;
+};
+
+unsigned int UserFontCallbacks::init_call_count = 0;
+unsigned int UserFontCallbacks::unicode_to_glyph_call_count = 0;
+unsigned int UserFontCallbacks::render_glyph_call_count = 0;
+
+void test_user_font_callbacks_mem()
+{
+ Cairo::RefPtr<Cairo::UserFontFace> font = Cairo::UserFontFace::create();
+ BOOST_CHECK(font);
+ UserFontCallbacks callbacks;
+ font->set_init_func(sigc::mem_fun(&callbacks, &UserFontCallbacks::init));
+ font->set_unicode_to_glyph_func(sigc::mem_fun(&callbacks,
+ &UserFontCallbacks::unicode_to_glyph));
+ font->set_render_glyph_func(sigc::mem_fun(&callbacks,
+ &UserFontCallbacks::render_glyph));
+ Cairo::RefPtr<Cairo::ScaledFont> scaled_font =
+ Cairo::ScaledFont::create(font, identity_matrix, identity_matrix,
+ Cairo::FontOptions());
+ BOOST_CHECK (UserFontCallbacks::init_call_count > 0);
+ Cairo::RefPtr<Cairo::ImageSurface> surface =
+ Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 100, 100);
+ Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
+ cr->set_font_face(font);
+ cr->show_text("Hello, world");
+ BOOST_CHECK (UserFontCallbacks::unicode_to_glyph_call_count > 0);
+ BOOST_CHECK (UserFontCallbacks::render_glyph_call_count > 0);
+}
+
+static unsigned int init_exception_call_count = 0;
+Cairo::ErrorStatus my_init_exception(const Cairo::RefPtr<Cairo::ScaledFont>&, const Cairo::RefPtr<Cairo::Context>&, Cairo::FontExtents&)
+{
+ init_exception_call_count++;
+ throw std::logic_error("init exception");
+}
+
+static unsigned int unicode_to_glyph_exception_call_count = 0;
+Cairo::ErrorStatus my_unicode_to_glyph_exception(const Cairo::RefPtr<Cairo::ScaledFont>&, unsigned long, unsigned long&)
+{
+ unicode_to_glyph_exception_call_count++;
+ throw std::logic_error("unicode-to-glyph exception");
+}
+
+static unsigned int render_glyph_exception_call_count = 0;
+Cairo::ErrorStatus my_render_glyph_exception(const Cairo::RefPtr<Cairo::ScaledFont>&, unsigned long, const Cairo::RefPtr<Cairo::Context>&, Cairo::TextExtents&)
+{
+ render_glyph_exception_call_count++;
+ throw std::logic_error("render-glyph exception");
+}
+
+
+void test_user_font_callbacks_exception()
+{
+ Cairo::RefPtr<Cairo::UserFontFace> font = Cairo::UserFontFace::create();
+ BOOST_CHECK(font);
+ font->set_init_func(sigc::ptr_fun(my_init_exception));
+
+ // the init() callback will throw an exception, if this isn't handled in the
+ // callback wrapper, the program will abort since an exception can't unwind
+ // through C code. However, due to the exception being thrown, the create()
+ // function will fail and throw a new exception. So if the executable doesn't
+ // abort, we should get an exception here.
+ Cairo::RefPtr<Cairo::ScaledFont> scaled_font;
+ BOOST_CHECK_THROW (scaled_font = Cairo::ScaledFont::create(font,
+ identity_matrix,
+ identity_matrix,
+ Cairo::FontOptions()),
+ Cairo::logic_error);
+ BOOST_CHECK (init_exception_call_count > 0);
+
+ // now initialize a scaled font properly so we can test the other callbacks
+ font = Cairo::UserFontFace::create();
+ font->set_init_func(sigc::ptr_fun(my_init));
+ font->set_render_glyph_func(sigc::ptr_fun(my_render_glyph_exception));
+ font->set_unicode_to_glyph_func(sigc::ptr_fun(my_unicode_to_glyph_exception));
+ BOOST_CHECK_NO_THROW (scaled_font = Cairo::ScaledFont::create(font,
+ identity_matrix,
+ identity_matrix,
+ Cairo::FontOptions()))
+ Cairo::RefPtr<Cairo::ImageSurface> surface =
+ Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 100, 100);
+ Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
+ cr->set_font_face(font);
+ // this call should throw an exception since the callback wrapper will return
+ // an error status (that will be translated into an exception) but the test
+ // shouldn't abort sindce the callback exceptions are handled by the callback
+ // wrapper
+ BOOST_REQUIRE_EQUAL (CAIRO_STATUS_SUCCESS, font->get_status());
+ BOOST_CHECK_THROW(cr->show_text("Hello, world"), Cairo::logic_error);
+ BOOST_CHECK (UserFontCallbacks::unicode_to_glyph_call_count > 0);
+ BOOST_CHECK (UserFontCallbacks::render_glyph_call_count > 0);
+}
+
+// create some dummy callbacks
+static unsigned int init2_call_count = 0;
+Cairo::ErrorStatus my_init2(const Cairo::RefPtr<Cairo::ScaledFont>&, const Cairo::RefPtr<Cairo::Context>&, Cairo::FontExtents&)
+{
+ init2_call_count++;
+ return CAIRO_STATUS_SUCCESS;
+}
+
+void test_user_font_replace_callback()
+{
+ // reset
+ init_call_count = 0;
+ Cairo::RefPtr<Cairo::UserFontFace> font = Cairo::UserFontFace::create();
+ font->set_init_func(sigc::ptr_fun(my_init));
+ // now replace the init function with my_init2 and make sure that the 2nd
+ // function is called, not the first
+ font->set_init_func(sigc::ptr_fun(my_init2));
+ Cairo::RefPtr<Cairo::ScaledFont> scaled_font;
+ BOOST_CHECK_NO_THROW (scaled_font = Cairo::ScaledFont::create(font,
+ identity_matrix,
+ identity_matrix,
+ Cairo::FontOptions()))
+ BOOST_CHECK (init2_call_count > 0);
+ BOOST_CHECK_EQUAL (init_call_count, 0);
+}
+
test_suite*
init_unit_test_suite(int argc, char* argv[])
@@ -43,10 +237,18 @@ init_unit_test_suite(int argc, char* argv[])
// compile even with -Werror
if (argc && argv) {}
+ // setup
+ cairo_matrix_init_identity(&identity_matrix);
+
test_suite* test= BOOST_TEST_SUITE( "Cairo::FontFace Tests" );
test->add (BOOST_TEST_CASE (&test_create_toy));
test->add (BOOST_TEST_CASE (&test_toy_getters));
+ test->add (BOOST_TEST_CASE (&test_user_font_create));
+ test->add (BOOST_TEST_CASE (&test_user_font_callbacks_ptr));
+ test->add (BOOST_TEST_CASE (&test_user_font_callbacks_mem));
+ test->add (BOOST_TEST_CASE (&test_user_font_callbacks_exception));
+ test->add (BOOST_TEST_CASE (&test_user_font_replace_callback));
return test;
}