static VALUE rpango_break(VALUE self, VALUE text, VALUE analysis) { gint i, len; glong attrs_len; PangoLogAttr *attrs; const gchar *gtext; VALUE ret; gtext = StringValuePtr(text); len = RSTRING_LEN(text); attrs_len = g_utf8_strlen(gtext, (gssize)len) + 1l; attrs = g_new0(PangoLogAttr, attrs_len); pango_break(gtext, len, NIL_P(analysis) ? NULL : RVAL2BOXED(analysis, PANGO_TYPE_ANALYSIS), attrs, attrs_len); ret = rb_ary_new(); for (i = 0; i < attrs_len; i++){ rb_ary_push(ret, BOXED2RVAL(&attrs[i], PANGO_TYPE_LOG_ATTR)); } g_free(attrs); return ret; }
/* uses Pango to find all possible line break locations in a message and returns a PangoLogAttr array which maps to each byte of the message of length one larger than the message. This must be g_free()'d */ static PangoLogAttr * find_all_breaks(const char *message) { PangoContext *context; PangoLogAttr *a; GList *list; gint len, n_attr; g_return_val_if_fail(message != NULL, NULL); len = strlen(message); n_attr = len+1; a = g_new0(PangoLogAttr, n_attr); /* init Pango */ context = splitter_create_pango_context(); g_return_val_if_fail(context != NULL, NULL); list = pango_itemize(context, message, 0, len, NULL, NULL); if (list != NULL && list->data != NULL) pango_break(message, -1, &((PangoItem*)(list->data))->analysis, a, n_attr); return a; }
static VALUE rg_s_break(G_GNUC_UNUSED VALUE self, VALUE rbtext, VALUE rbanalysis) { const gchar *text = RVAL2CSTR(rbtext); long length = RSTRING_LEN(rbtext); PangoAnalysis *analysis = RVAL2PANGOANALYSIS(rbanalysis); long n = g_utf8_strlen(text, length) + 1; PangoLogAttr *attrs = g_new(PangoLogAttr, n); pango_break(text, length, analysis, attrs, n); return PANGOLOGATTRS2RVAL_FREE(attrs, n); }