summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathon Jongsma <jjongsma@gnome.org>2008-12-07 22:14:40 -0600
committerJonathon Jongsma <jjongsma@gnome.org>2008-12-08 22:33:48 -0600
commitba26ea83e95563e8cc32223f2dbe4d8ea7089563 (patch)
tree4555b7219cd2e86ea6d07648b5eb2655f407b70f
parent3be1dc30c7ff2562eb19bcab278610d44e9ba13c (diff)
Fix the UserFontFace::text_to_glyphs default vfunc
* cairomm/fontface.cc: 'fix' the text_to_glyphs implementation so that the default virtual function will be bypassed and the unicode_to_glyph will be called instead. This is done in the C implementation by passing a negative value for the num_glyphs output parameter, but since we're using a std::vector for the glyphs, it's not possible to return a negative value. So I'm using an ugly hack that will set a boolean flag the first time the default text_to_glyphs vfunc is called (which implies that that function has not been reimplemented in a derived class), and if we check that boolean flag and it is set, we will pass a negative value down to the C caller
-rw-r--r--ChangeLog12
-rw-r--r--cairomm/fontface.cc23
2 files changed, 33 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 3934456..f384c15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2008-12-07 Jonathon Jongsma <jonathon@quotidian.org>
+ * cairomm/fontface.cc: 'fix' the text_to_glyphs implementation so that the
+ default virtual function will be bypassed and the unicode_to_glyph will be
+ called instead. This is done in the C implementation by passing a negative
+ value for the num_glyphs output parameter, but since we're using a std::vector
+ for the glyphs, it's not possible to return a negative value. So I'm using an
+ ugly hack that will set a boolean flag the first time the default
+ text_to_glyphs vfunc is called (which implies that that function has not been
+ reimplemented in a derived class), and if we check that boolean flag and it is
+ set, we will pass a negative value down to the C caller
+
+2008-12-07 Jonathon Jongsma <jonathon@quotidian.org>
+
* cairomm/fontface.cc:
* cairomm/fontface.h: Change UserFontFace implementation to a vfunc-based
implementation rather than requiring people to supply callbacks at runtime as
diff --git a/cairomm/fontface.cc b/cairomm/fontface.cc
index 840a762..0a57320 100644
--- a/cairomm/fontface.cc
+++ b/cairomm/fontface.cc
@@ -25,6 +25,8 @@
namespace Cairo
{
+const cairo_user_data_key_t USER_DATA_KEY_DEFAULT_TEXT_TO_GLYPHS = {0};
+
FontFace::FontFace(cairo_font_face_t* cobject, bool has_reference)
: m_cobject(0)
{
@@ -233,6 +235,13 @@ UserFontFace::text_to_glyphs_cb(cairo_scaled_font_t *scaled_font,
ScaledFont(scaled_font)),
utf8_str, glyph_v, cluster_v, local_flags);
+ // NOTE: see explanation in text_to_glyphs()
+ if (cairo_font_face_get_user_data(face, &USER_DATA_KEY_DEFAULT_TEXT_TO_GLYPHS))
+ {
+ *num_glyphs = -1;
+ return status;
+ }
+
// TODO: we re-allocate a new array and pass it back to the caller since
// cairo will free the the returned array. It sucks to do this excessive
// allocation and copying, I don't see much alternative besides just
@@ -287,8 +296,18 @@ UserFontFace::text_to_glyphs(const RefPtr<ScaledFont>& /*scaled_font*/,
std::vector<TextCluster>& /*clusters*/,
TextClusterFlags& /*cluster_flags*/)
{
- // FIXME: default implementation should return -1 for num_glyphs, but there's not
- // really any way to do that with the current interface
+ // this is a big hack to make up for the fact that we can't easily pass back a
+ // negative value for the size of the glyph array, which is a special value in
+ // the C API that means: "ignore this function and call unicode_to_glyph
+ // instead". If this default virtual function is ever called, it will set a
+ // bool value in the user_data, which we can read back in the
+ // text_to_glyphs_cb and used as a signal to return -1 for the num_glyphs
+ // parameter.
+ static bool first_time = true;
+ if (first_time) {
+ cairo_font_face_set_user_data(cobj(), &USER_DATA_KEY_DEFAULT_TEXT_TO_GLYPHS, reinterpret_cast<void*>(true), NULL);
+ first_time = false;
+ }
return CAIRO_STATUS_SUCCESS;
}