static cairo_status_t test_scaled_font_text_to_glyphs (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_scaled_font_t *fallback_scaled_font; fallback_scaled_font = cairo_scaled_font_get_user_data (scaled_font, &fallback_font_key); return cairo_scaled_font_text_to_glyphs (fallback_scaled_font, 0, 0, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags); }
static cairo_status_t twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *metrics) { double x1, y1, x2, y2, x3, y3; double marginl; twin_scaled_properties_t *props; twin_snap_info_t info; const int8_t *b; const int8_t *g; int8_t w; double gw; props = cairo_scaled_font_get_user_data (scaled_font, &twin_properties_key); /* Save glyph space, we need it when stroking */ cairo_save (cr); /* center the pen */ cairo_translate (cr, props->penx * .5, -props->peny * .5); /* small-caps */ if (props->face_props->smallcaps && glyph >= 'a' && glyph <= 'z') { glyph += 'A' - 'a'; /* 28 and 42 are small and capital letter heights of the glyph data */ cairo_scale (cr, 1, 28. / 42); } /* slant */ if (props->face_props->slant != CAIRO_FONT_SLANT_NORMAL) { cairo_matrix_t shear = { 1, 0, -.2, 1, 0, 0}; cairo_transform (cr, &shear); } b = _cairo_twin_outlines + _cairo_twin_charmap[unlikely (glyph >= ARRAY_LENGTH (_cairo_twin_charmap)) ? 0 : glyph]; g = twin_glyph_draw(b); w = twin_glyph_right(b); gw = F(w); marginl = props->marginl; /* monospace */ if (props->face_props->monospace) { double monow = F(24); double extra = props->penx + props->marginl + props->marginr; cairo_scale (cr, (monow + extra) / (gw + extra), 1); gw = monow; /* resnap margin for new transform */ { double x, y, x_scale, x_scale_inv; x = 1; y = 0; compute_hinting_scale (cr, x, y, &x_scale, &x_scale_inv); marginl = SNAPXI (marginl); } } cairo_translate (cr, marginl, 0); /* stretch */ cairo_scale (cr, props->stretch, 1); if (props->snap) twin_compute_snap (cr, &info, b); else info.n_snap_x = info.n_snap_y = 0; /* advance width */ metrics->x_advance = gw * props->stretch + props->penx + props->marginl + props->marginr; /* glyph shape */ for (;;) { switch (*g++) { case 'M': cairo_close_path (cr); /* fall through */ case 'm': x1 = SNAPX(*g++); y1 = SNAPY(*g++); cairo_move_to (cr, x1, y1); continue; case 'L': cairo_close_path (cr); /* fall through */ case 'l': x1 = SNAPX(*g++); y1 = SNAPY(*g++); cairo_line_to (cr, x1, y1); continue; case 'C': cairo_close_path (cr); /* fall through */ case 'c': x1 = SNAPX(*g++); y1 = SNAPY(*g++); x2 = SNAPX(*g++); y2 = SNAPY(*g++); x3 = SNAPX(*g++); y3 = SNAPY(*g++); cairo_curve_to (cr, x1, y1, x2, y2, x3, y3); continue; case 'E': cairo_close_path (cr); /* fall through */ case 'e': cairo_restore (cr); /* restore glyph space */ cairo_set_tolerance (cr, 0.01); cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cr, 1); cairo_scale (cr, props->penx, props->peny); cairo_stroke (cr); break; case 'X': /* filler */ continue; } break; } return CAIRO_STATUS_SUCCESS; }