static cairo_status_t cr_user_font_face_unicode_to_glyph_func (cairo_scaled_font_t *scaled_font, unsigned long unicode, unsigned long *glyph_index) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_font_face_t *face; VALUE self; VALUE receiver = Qnil; ID id_method_name = cr_id_call; face = cairo_scaled_font_get_font_face (scaled_font); self = (VALUE)cairo_font_face_get_user_data (face, &ruby_object_key); receiver = rb_ivar_get (self, cr_id_unicode_to_glyph); if (NIL_P (receiver) && rb_obj_respond_to (self, cr_id_unicode_to_glyph, Qtrue)) { receiver = self; id_method_name = cr_id_unicode_to_glyph; } if (NIL_P (receiver)) { *glyph_index = unicode; } else { cr_user_font_face_invoke_data_t data; VALUE argv[2]; argv[0] = CRSCALEDFONT2RVAL (scaled_font); argv[1] = ULONG2NUM (unicode); data.receiver = receiver; data.method = id_method_name; data.argc = 2; data.argv = argv; data.status = &status; data.after_hook = cr_user_font_face_unicode_to_glyph_func_after; data.after_hook_data = glyph_index; rb_cairo__invoke_callback (cr_user_font_face_invoke_func, (VALUE)&data); } return status; }
static cairo_status_t cr_user_font_face_render_glyph_func (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *extents) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_font_face_t *face; VALUE self; VALUE receiver = Qnil; ID id_method_name = cr_id_call; face = cairo_scaled_font_get_font_face (scaled_font); self = (VALUE)cairo_font_face_get_user_data (face, &ruby_object_key); receiver = rb_ivar_get (self, cr_id_render_glyph); if (NIL_P (receiver) && rb_obj_respond_to (self, cr_id_render_glyph, Qtrue)) { receiver = self; id_method_name = cr_id_render_glyph; } if (!NIL_P (receiver)) { cr_user_font_face_invoke_data_t data; VALUE argv[4]; argv[0] = CRSCALEDFONT2RVAL (scaled_font); argv[1] = ULONG2NUM (glyph); argv[2] = CRCONTEXT2RVAL (cr); argv[3] = CRTEXTEXTENTS2RVAL (extents); data.receiver = receiver; data.method = id_method_name; data.argc = 4; data.argv = argv; data.status = &status; data.after_hook = cr_user_font_face_render_glyph_func_after; data.after_hook_data = extents; rb_cairo__invoke_callback (cr_user_font_face_invoke_func, (VALUE)&data); } return status; }
static VALUE cr_get_scaled_font (VALUE self) { return CRSCALEDFONT2RVAL (cairo_get_scaled_font (_SELF)); }
static cairo_status_t cr_user_font_face_text_to_glyphs_func (cairo_scaled_font_t *scaled_font, const char *utf8, int utf8_len, cairo_glyph_t **glyphs, int *num_glyphs, cairo_text_cluster_t **clusters, int *num_clusters, cairo_text_cluster_flags_t *cluster_flags) { cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; cairo_font_face_t *face; VALUE self; VALUE receiver = Qnil; ID id_method_name = cr_id_call; face = cairo_scaled_font_get_font_face (scaled_font); self = (VALUE)cairo_font_face_get_user_data (face, &ruby_object_key); receiver = rb_ivar_get (self, cr_id_text_to_glyphs); if (NIL_P (receiver) && rb_obj_respond_to (self, cr_id_text_to_glyphs, Qtrue)) { receiver = self; id_method_name = cr_id_text_to_glyphs; } if (NIL_P (receiver)) { if (num_glyphs) *num_glyphs = -1; } else { cr_user_font_face_invoke_data_t data; cr_text_to_glyphs_after_hook_data_t after_hook_data; VALUE text_to_glyphs_data; VALUE argv[3]; argv[0] = CRSCALEDFONT2RVAL (scaled_font); argv[1] = rb_str_new (utf8, utf8_len); text_to_glyphs_data = rb_funcall (rb_cCairo_UserFontFace_TextToGlyphsData, cr_id_new, 3, CBOOL2RVAL (glyphs != NULL), CBOOL2RVAL (clusters != NULL), CBOOL2RVAL (cluster_flags != NULL)); argv[2] = text_to_glyphs_data; data.receiver = receiver; data.method = id_method_name; data.argc = 3; data.argv = argv; data.status = &status; data.after_hook = cr_user_font_face_text_to_glyphs_func_after; data.after_hook_data = &after_hook_data; after_hook_data.text_to_glyphs_data = text_to_glyphs_data; after_hook_data.glyphs = glyphs; after_hook_data.num_glyphs = num_glyphs; after_hook_data.clusters = clusters; after_hook_data.num_clusters = num_clusters; after_hook_data.cluster_flags = cluster_flags; rb_cairo__invoke_callback (cr_user_font_face_invoke_func, (VALUE)&data); } return status; }