static VALUE cr_show_text_glyphs (VALUE self, VALUE rb_utf8, VALUE rb_glyphs, VALUE rb_clusters, VALUE rb_cluster_flags) { cairo_t *cr; const char *utf8; int utf8_len; cairo_glyph_t *glyphs = NULL; int num_glyphs = 0; cairo_text_cluster_t *clusters = NULL; int num_clusters = 0; cairo_text_cluster_flags_t cluster_flags; cr = _SELF; utf8 = RSTRING_PTR (rb_utf8); utf8_len = RSTRING_LEN (rb_utf8); rb_cairo__glyphs_from_ruby_object (rb_glyphs, &glyphs, &num_glyphs); rb_cairo__text_clusters_from_ruby_object (rb_clusters, &clusters, &num_clusters); cluster_flags = RVAL2CRTEXTCLUSTERFLAGS (rb_cluster_flags); cairo_show_text_glyphs (cr, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags); if (glyphs) cairo_glyph_free (glyphs); if (clusters) cairo_text_cluster_free (clusters); return self; }
size_t render(const string& text, double x = 0.0, double y = 0.0) override { cairo_glyph_t* glyphs{nullptr}; cairo_text_cluster_t* clusters{nullptr}; cairo_text_cluster_flags_t cf{}; int nglyphs = 0, nclusters = 0; string utf8 = string(text); auto status = cairo_scaled_font_text_to_glyphs( m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf); if (status != CAIRO_STATUS_SUCCESS) { throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status)); } size_t bytes = 0; for (int g = 0; g < nglyphs; g++) { if (glyphs[g].index) { bytes += clusters[g].num_bytes; } else { break; } } if (bytes && bytes < text.size()) { cairo_glyph_free(glyphs); cairo_text_cluster_free(clusters); utf8 = text.substr(0, bytes); auto status = cairo_scaled_font_text_to_glyphs( m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf); if (status != CAIRO_STATUS_SUCCESS) { throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status)); } } if (bytes) { // auto lock = make_unique<utils::device_lock>(cairo_surface_get_device(cairo_get_target(m_cairo))); // if (lock.get()) { // cairo_glyph_path(m_cairo, glyphs, nglyphs); // } cairo_text_extents_t extents{}; cairo_scaled_font_glyph_extents(m_scaled, glyphs, nglyphs, &extents); cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf); cairo_fill(m_cairo); cairo_move_to(m_cairo, x + extents.x_advance, 0.0); } cairo_glyph_free(glyphs); cairo_text_cluster_free(clusters); return bytes; }
static int cr_show_text_glyphs (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); size_t text_len; const char *text = luaL_checklstring(L, 2, &text_len); cairo_glyph_t *glyphs; cairo_text_cluster_t *clusters; cairo_text_cluster_flags_t cluster_flags; int num_glyphs, num_clusters; from_lua_glyph_array(L, &glyphs, &num_glyphs, 3); from_lua_clusters_table(L, &clusters, &num_clusters, &cluster_flags, 4); cairo_show_text_glyphs(*obj, text, text_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags); if (glyphs) GLYPHS_FREE(glyphs); if (clusters) cairo_text_cluster_free(clusters); return 0; }