mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-03-22 17:20:37 +01:00
Add cairo_scaled_font_text_to_glyphs()
And update user-font text_to_glyphs() method to match. Currently disable the win32-font text_to_glyphs(), until that one is updated. Or better yet, remove it and implement ucs4_to_index(). It's the toy font API afterall.
This commit is contained in:
parent
b8fc845094
commit
d9408041aa
8 changed files with 301 additions and 128 deletions
|
|
@ -1445,12 +1445,16 @@ _cairo_gstate_get_font_extents (cairo_gstate_t *gstate,
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
|
||||
const char *utf8,
|
||||
double x,
|
||||
double y,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs)
|
||||
_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
int *num_clusters,
|
||||
cairo_bool_t *backward)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
|
@ -1458,8 +1462,11 @@ _cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
return _cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
|
||||
utf8, glyphs, num_glyphs);
|
||||
return cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y,
|
||||
utf8, utf8_len,
|
||||
glyphs, num_glyphs,
|
||||
clusters, num_clusters,
|
||||
backward);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
|
|
@ -1536,7 +1543,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
|||
if (num_glyphs <= ARRAY_LENGTH (stack_transformed_glyphs)) {
|
||||
transformed_glyphs = stack_transformed_glyphs;
|
||||
} else {
|
||||
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
|
||||
transformed_glyphs = cairo_glyph_allocate (num_glyphs);
|
||||
if (transformed_glyphs == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
|
@ -1551,6 +1558,10 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
|||
if (status)
|
||||
goto CLEANUP_GLYPHS;
|
||||
|
||||
/* Just in case */
|
||||
if (!clusters)
|
||||
num_clusters = 0;
|
||||
|
||||
/* For really huge font sizes, we can just do path;fill instead of
|
||||
* show_glyphs, as show_glyphs would put excess pressure on the cache,
|
||||
* and moreover, not all components below us correctly handle huge font
|
||||
|
|
@ -1598,7 +1609,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
|||
|
||||
CLEANUP_GLYPHS:
|
||||
if (transformed_glyphs != stack_transformed_glyphs)
|
||||
free (transformed_glyphs);
|
||||
cairo_glyph_free (transformed_glyphs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -1620,7 +1631,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
|||
if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs))
|
||||
transformed_glyphs = stack_transformed_glyphs;
|
||||
else
|
||||
transformed_glyphs = _cairo_malloc_ab (num_glyphs, sizeof(cairo_glyph_t));
|
||||
transformed_glyphs = cairo_glyph_allocate (num_glyphs);
|
||||
if (transformed_glyphs == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
|
|
@ -1634,7 +1645,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
|
|||
CAIRO_MUTEX_UNLOCK (gstate->scaled_font->mutex);
|
||||
|
||||
if (transformed_glyphs != stack_transformed_glyphs)
|
||||
free (transformed_glyphs);
|
||||
cairo_glyph_free (transformed_glyphs);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1109,7 +1109,7 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font,
|
|||
cairo_text_extents_t *extents)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_glyph_t *glyphs;
|
||||
cairo_glyph_t *glyphs = NULL;
|
||||
int num_glyphs;
|
||||
|
||||
if (scaled_font->status)
|
||||
|
|
@ -1118,7 +1118,11 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font,
|
|||
if (utf8 == NULL)
|
||||
goto ZERO_EXTENTS;
|
||||
|
||||
status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs);
|
||||
status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0.,
|
||||
utf8, -1,
|
||||
&glyphs, &num_glyphs,
|
||||
NULL, NULL,
|
||||
NULL);
|
||||
if (status)
|
||||
goto ZERO_EXTENTS;
|
||||
|
||||
|
|
@ -1265,70 +1269,148 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
|||
slim_hidden_def (cairo_scaled_font_glyph_extents);
|
||||
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs)
|
||||
cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
int *num_clusters,
|
||||
cairo_bool_t *backward)
|
||||
{
|
||||
int i;
|
||||
uint32_t *ucs4 = NULL;
|
||||
int num_chars = 0;
|
||||
const char *p;
|
||||
cairo_status_t status;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
||||
*num_glyphs = 0;
|
||||
*glyphs = NULL;
|
||||
cairo_glyph_t *orig_glyphs;
|
||||
cairo_text_cluster_t *orig_clusters;
|
||||
|
||||
status = scaled_font->status;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (utf8[0] == '\0')
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
/* A slew of sanity checks */
|
||||
|
||||
/* glyphs and num_glyphs can't be NULL */
|
||||
if (glyphs == NULL ||
|
||||
num_glyphs == NULL) {
|
||||
status = CAIRO_STATUS_NULL_POINTER;
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
/* No NULLs for non-NULLs! */
|
||||
if ((utf8_len && utf8 == NULL) ||
|
||||
(clusters && num_clusters == NULL) ||
|
||||
(clusters && backward == NULL)) {
|
||||
status = CAIRO_STATUS_NULL_POINTER;
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
/* A -1 for utf8_len means NUL-terminated */
|
||||
if (utf8_len == -1)
|
||||
utf8_len = strlen (utf8);
|
||||
|
||||
/* A NULL *glyphs means no prealloced glyphs array */
|
||||
if (glyphs && *glyphs == NULL)
|
||||
*num_glyphs = 0;
|
||||
|
||||
/* A NULL *clusters means no prealloced clusters array */
|
||||
if (clusters && *clusters == NULL)
|
||||
*num_clusters = 0;
|
||||
|
||||
if (!clusters && num_clusters) {
|
||||
num_clusters = NULL;
|
||||
}
|
||||
|
||||
if (backward) {
|
||||
*backward = FALSE;
|
||||
}
|
||||
|
||||
if (!clusters && backward) {
|
||||
backward = NULL;
|
||||
}
|
||||
|
||||
/* Apart from that, no negatives */
|
||||
if (utf8_len < 0 ||
|
||||
*num_glyphs < 0 ||
|
||||
(num_clusters && *num_clusters < 0)) {
|
||||
status = CAIRO_STATUS_NEGATIVE_COUNT;
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
if (utf8_len == 0) {
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
/* validate input so backend does not have to */
|
||||
status = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, &num_chars);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
CAIRO_MUTEX_LOCK (scaled_font->mutex);
|
||||
_cairo_scaled_font_freeze_cache (scaled_font);
|
||||
|
||||
orig_glyphs = *glyphs;
|
||||
orig_clusters = clusters ? *clusters : NULL;
|
||||
|
||||
if (scaled_font->backend->text_to_glyphs) {
|
||||
|
||||
/* validate input so backend does not have to */
|
||||
status = _cairo_utf8_to_ucs4 (utf8, -1, NULL, NULL);
|
||||
if (status)
|
||||
goto DONE;
|
||||
|
||||
status = scaled_font->backend->text_to_glyphs (scaled_font,
|
||||
x, y, utf8,
|
||||
glyphs, num_glyphs);
|
||||
status = scaled_font->backend->text_to_glyphs (scaled_font, x, y,
|
||||
utf8, utf8_len,
|
||||
glyphs, num_glyphs,
|
||||
clusters, num_clusters,
|
||||
backward);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
status = _cairo_utf8_to_ucs4 (utf8, -1, &ucs4, num_glyphs);
|
||||
if (status)
|
||||
goto DONE;
|
||||
if (*num_glyphs < num_chars) {
|
||||
*glyphs = cairo_glyph_allocate (num_chars);
|
||||
if (*glyphs == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
*num_glyphs = num_chars;
|
||||
|
||||
*glyphs = (cairo_glyph_t *) _cairo_malloc_ab ((*num_glyphs), sizeof (cairo_glyph_t));
|
||||
|
||||
if (*glyphs == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto DONE;
|
||||
if (clusters) {
|
||||
if (*num_clusters < num_chars) {
|
||||
*clusters = cairo_text_cluster_allocate (num_chars);
|
||||
if (*clusters == NULL) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
*num_clusters = num_chars;
|
||||
}
|
||||
|
||||
for (i = 0; i < *num_glyphs; i++) {
|
||||
(*glyphs)[i].index = (*scaled_font->backend->
|
||||
ucs4_to_index) (scaled_font, ucs4[i]);
|
||||
p = utf8;
|
||||
for (i = 0; i < num_chars; i++) {
|
||||
int num_bytes;
|
||||
uint32_t unicode;
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
|
||||
num_bytes = _cairo_utf8_get_char_validated (p, &unicode);
|
||||
p += num_bytes;
|
||||
|
||||
(*glyphs)[i].index = (*scaled_font->backend->ucs4_to_index) (scaled_font, unicode);
|
||||
(*glyphs)[i].x = x;
|
||||
(*glyphs)[i].y = y;
|
||||
|
||||
if (clusters) {
|
||||
(*clusters)[i].num_bytes = num_bytes;
|
||||
(*clusters)[i].num_glyphs = 1;
|
||||
}
|
||||
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
(*glyphs)[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
&scaled_glyph);
|
||||
if (status) {
|
||||
free (*glyphs);
|
||||
*glyphs = NULL;
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
|
|
@ -1336,14 +1418,37 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
y += scaled_glyph->metrics.y_advance;
|
||||
}
|
||||
|
||||
DONE:
|
||||
DONE: /* error that should be logged on scaled_font happened */
|
||||
_cairo_scaled_font_thaw_cache (scaled_font);
|
||||
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
|
||||
|
||||
if (ucs4)
|
||||
free (ucs4);
|
||||
if (status) {
|
||||
*num_glyphs = 0;
|
||||
if (*glyphs != orig_glyphs) {
|
||||
cairo_glyph_free (*glyphs);
|
||||
*glyphs = orig_glyphs;
|
||||
}
|
||||
|
||||
if (clusters) {
|
||||
*num_clusters = 0;
|
||||
if (*clusters != orig_clusters) {
|
||||
cairo_text_cluster_free (*clusters);
|
||||
*clusters = orig_clusters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _cairo_scaled_font_set_error (scaled_font, status);
|
||||
|
||||
BAIL: /* error with input arguments */
|
||||
|
||||
if (num_glyphs)
|
||||
*num_glyphs = 0;
|
||||
|
||||
if (num_clusters)
|
||||
*num_clusters = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -265,12 +265,16 @@ _cairo_user_ucs4_to_index (void *abstract_font,
|
|||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_user_text_to_glyphs (void *abstract_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs)
|
||||
_cairo_user_text_to_glyphs (void *abstract_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
int *num_clusters,
|
||||
cairo_bool_t *backward)
|
||||
{
|
||||
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
|
@ -280,25 +284,21 @@ _cairo_user_text_to_glyphs (void *abstract_font,
|
|||
|
||||
if (face->scaled_font_methods.text_to_glyphs) {
|
||||
int i;
|
||||
int orig_num_glyphs = *num_glyphs;
|
||||
|
||||
*glyphs = NULL;
|
||||
*num_glyphs = -1;
|
||||
|
||||
/* XXX currently user allocs glyphs array but cairo frees it */
|
||||
status = face->scaled_font_methods.text_to_glyphs (&scaled_font->base,
|
||||
utf8, glyphs, num_glyphs);
|
||||
utf8, utf8_len,
|
||||
glyphs, num_glyphs,
|
||||
clusters, num_clusters,
|
||||
backward);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS) {
|
||||
status = _cairo_scaled_font_set_error (&scaled_font->base, status);
|
||||
if (*glyphs) {
|
||||
free (*glyphs);
|
||||
*glyphs = NULL;
|
||||
}
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (*num_glyphs < 0)
|
||||
if (*num_glyphs < 0) {
|
||||
*num_glyphs = orig_num_glyphs;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Convert from font space to user space and add x,y */
|
||||
for (i = 0; i < *num_glyphs; i++) {
|
||||
|
|
|
|||
|
|
@ -1780,7 +1780,7 @@ const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = {
|
|||
_cairo_win32_scaled_font_create_toy,
|
||||
_cairo_win32_scaled_font_fini,
|
||||
_cairo_win32_scaled_font_glyph_init,
|
||||
_cairo_win32_scaled_font_text_to_glyphs,
|
||||
/* _cairo_win32_scaled_font_text_to_glyphs, FIXME */
|
||||
NULL, /* ucs4_to_index */
|
||||
_cairo_win32_scaled_font_show_glyphs,
|
||||
_cairo_win32_scaled_font_load_truetype_table,
|
||||
|
|
|
|||
59
src/cairo.c
59
src/cairo.c
|
|
@ -3013,16 +3013,18 @@ cairo_text_extents (cairo_t *cr,
|
|||
|
||||
cairo_get_current_point (cr, &x, &y);
|
||||
|
||||
status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
|
||||
status = _cairo_gstate_text_to_glyphs (cr->gstate,
|
||||
x, y,
|
||||
&glyphs, &num_glyphs);
|
||||
utf8, strlen (utf8),
|
||||
&glyphs, &num_glyphs,
|
||||
NULL, NULL,
|
||||
NULL);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_gstate_glyph_extents (cr->gstate,
|
||||
glyphs, num_glyphs,
|
||||
extents);
|
||||
if (glyphs)
|
||||
free (glyphs);
|
||||
cairo_glyph_free (glyphs);
|
||||
|
||||
if (status)
|
||||
_cairo_set_error (cr, status);
|
||||
|
|
@ -3116,7 +3118,9 @@ cairo_show_text (cairo_t *cr, const char *utf8)
|
|||
cairo_text_extents_t extents;
|
||||
cairo_status_t status;
|
||||
cairo_glyph_t *glyphs = NULL, *last_glyph;
|
||||
int num_glyphs;
|
||||
cairo_text_cluster_t *clusters = NULL;
|
||||
int utf8_len, num_glyphs, num_clusters;
|
||||
cairo_bool_t backward;
|
||||
double x, y;
|
||||
|
||||
if (cr->status)
|
||||
|
|
@ -3127,9 +3131,14 @@ cairo_show_text (cairo_t *cr, const char *utf8)
|
|||
|
||||
cairo_get_current_point (cr, &x, &y);
|
||||
|
||||
status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
|
||||
utf8_len = strlen (utf8);
|
||||
|
||||
status = _cairo_gstate_text_to_glyphs (cr->gstate,
|
||||
x, y,
|
||||
&glyphs, &num_glyphs);
|
||||
utf8, utf8_len,
|
||||
&glyphs, &num_glyphs,
|
||||
cairo_has_show_text_glyphs (cr) ? &clusters : NULL, &num_clusters,
|
||||
&backward);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
|
|
@ -3137,10 +3146,10 @@ cairo_show_text (cairo_t *cr, const char *utf8)
|
|||
return;
|
||||
|
||||
status = _cairo_gstate_show_text_glyphs (cr->gstate,
|
||||
NULL, 0,
|
||||
utf8, utf8_len,
|
||||
glyphs, num_glyphs,
|
||||
NULL, 0,
|
||||
FALSE);
|
||||
clusters, num_clusters,
|
||||
backward);
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
||||
|
|
@ -3156,8 +3165,8 @@ cairo_show_text (cairo_t *cr, const char *utf8)
|
|||
cairo_move_to (cr, x, y);
|
||||
|
||||
BAIL:
|
||||
if (glyphs)
|
||||
free (glyphs);
|
||||
cairo_glyph_free (glyphs);
|
||||
cairo_text_cluster_free (clusters);
|
||||
|
||||
if (status)
|
||||
_cairo_set_error (cr, status);
|
||||
|
|
@ -3226,6 +3235,14 @@ cairo_show_text_glyphs (cairo_t *cr,
|
|||
|
||||
/* A slew of sanity checks */
|
||||
|
||||
/* No NULLs for non-zeros */
|
||||
if ((num_glyphs && glyphs == NULL) ||
|
||||
(utf8_len && utf8 == NULL) ||
|
||||
(num_clusters && clusters == NULL)) {
|
||||
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
|
||||
return;
|
||||
}
|
||||
|
||||
/* A -1 for utf8_len means NUL-terminated */
|
||||
if (utf8_len == -1)
|
||||
utf8_len = strlen (utf8);
|
||||
|
|
@ -3236,14 +3253,6 @@ cairo_show_text_glyphs (cairo_t *cr,
|
|||
return;
|
||||
}
|
||||
|
||||
/* And no NULLs for non-zeros */
|
||||
if ((num_glyphs && glyphs == NULL) ||
|
||||
(utf8_len && utf8 == NULL) ||
|
||||
(num_clusters && clusters == NULL)) {
|
||||
_cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure clusters cover the entire glyphs and utf8 arrays,
|
||||
* and that cluster boundaries are UTF-8 boundaries. */
|
||||
{
|
||||
|
|
@ -3343,9 +3352,12 @@ cairo_text_path (cairo_t *cr, const char *utf8)
|
|||
|
||||
cairo_get_current_point (cr, &x, &y);
|
||||
|
||||
status = _cairo_gstate_text_to_glyphs (cr->gstate, utf8,
|
||||
status = _cairo_gstate_text_to_glyphs (cr->gstate,
|
||||
x, y,
|
||||
&glyphs, &num_glyphs);
|
||||
utf8, strlen (utf8),
|
||||
&glyphs, &num_glyphs,
|
||||
NULL, NULL,
|
||||
NULL);
|
||||
|
||||
if (status)
|
||||
goto BAIL;
|
||||
|
|
@ -3373,8 +3385,7 @@ cairo_text_path (cairo_t *cr, const char *utf8)
|
|||
cairo_move_to (cr, x, y);
|
||||
|
||||
BAIL:
|
||||
if (glyphs)
|
||||
free (glyphs);
|
||||
cairo_glyph_free (glyphs);
|
||||
|
||||
if (status)
|
||||
_cairo_set_error (cr, status);
|
||||
|
|
|
|||
23
src/cairo.h
23
src/cairo.h
|
|
@ -1330,6 +1330,18 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font,
|
|||
int num_glyphs,
|
||||
cairo_text_extents_t *extents);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
int *num_clusters,
|
||||
cairo_bool_t *backward);
|
||||
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font);
|
||||
|
||||
|
|
@ -1468,6 +1480,7 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal
|
|||
* @glyphs: output array of glyphs, in font space
|
||||
* @num_glyphs: number of output glyphs
|
||||
*
|
||||
* XXXXXXXXXXXXX
|
||||
* #cairo_user_scaled_font_text_to_glyphs_func_t is the type of function which
|
||||
* is called to convert input text to an array of glyphs. This is used by the
|
||||
* cairo_show_text() operation.
|
||||
|
|
@ -1496,9 +1509,13 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal
|
|||
* Since: 1.8
|
||||
**/
|
||||
typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_scaled_font_t *scaled_font,
|
||||
const char *utf8,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs);
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
int *num_clusters,
|
||||
cairo_bool_t *backward);
|
||||
|
||||
/**
|
||||
* cairo_user_scaled_font_unicode_to_glyph_func_t:
|
||||
|
|
|
|||
|
|
@ -408,12 +408,16 @@ struct _cairo_scaled_font_backend {
|
|||
* then just converting characters one by one.
|
||||
*/
|
||||
cairo_warn cairo_int_status_t
|
||||
(*text_to_glyphs) (void *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs);
|
||||
(*text_to_glyphs) (void *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
int *num_clusters,
|
||||
cairo_bool_t *backward);
|
||||
|
||||
unsigned long
|
||||
(*ucs4_to_index) (void *scaled_font,
|
||||
|
|
@ -1219,12 +1223,16 @@ _cairo_gstate_set_font_face (cairo_gstate_t *gstate,
|
|||
cairo_font_face_t *font_face);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_text_to_glyphs (cairo_gstate_t *font,
|
||||
const char *utf8,
|
||||
double x,
|
||||
double y,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs);
|
||||
_cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
int utf8_len,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
int *num_clusters,
|
||||
cairo_bool_t *backward);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_gstate_glyph_extents (cairo_gstate_t *gstate,
|
||||
|
|
@ -1528,14 +1536,6 @@ cairo_private cairo_status_t
|
|||
_cairo_scaled_font_font_extents (cairo_scaled_font_t *scaled_font,
|
||||
cairo_font_extents_t *extents);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
double x,
|
||||
double y,
|
||||
const char *utf8,
|
||||
cairo_glyph_t **glyphs,
|
||||
int *num_glyphs);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||
const cairo_glyph_t *glyphs,
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ cairo_test_t test = {
|
|||
draw
|
||||
};
|
||||
|
||||
static cairo_user_data_key_t fallback_font_face_key;
|
||||
static cairo_user_data_key_t fallback_font_key;
|
||||
|
||||
static cairo_status_t
|
||||
test_scaled_font_init (cairo_scaled_font_t *scaled_font,
|
||||
|
|
@ -60,7 +60,12 @@ test_scaled_font_init (cairo_scaled_font_t *scaled_font,
|
|||
{
|
||||
cairo_set_font_face (cr,
|
||||
cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
|
||||
&fallback_font_face_key));
|
||||
&fallback_font_key));
|
||||
|
||||
cairo_scaled_font_set_user_data (scaled_font,
|
||||
&fallback_font_key,
|
||||
cairo_scaled_font_reference (cairo_get_scaled_font (cr)),
|
||||
(cairo_destroy_func_t) cairo_scaled_font_destroy);
|
||||
|
||||
cairo_font_extents (cr, extents);
|
||||
|
||||
|
|
@ -73,21 +78,44 @@ test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font,
|
|||
cairo_t *cr,
|
||||
cairo_text_extents_t *extents)
|
||||
{
|
||||
char text[2] = "\0";
|
||||
cairo_glyph_t cairo_glyph;
|
||||
|
||||
/* XXX only works for ASCII. need ucs4_to_utf8 :( */
|
||||
text[0] = glyph;
|
||||
cairo_glyph.index = glyph;
|
||||
cairo_glyph.x = 0;
|
||||
cairo_glyph.y = 0;
|
||||
|
||||
cairo_set_font_face (cr,
|
||||
cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
|
||||
&fallback_font_face_key));
|
||||
&fallback_font_key));
|
||||
|
||||
cairo_show_text (cr, text);
|
||||
cairo_text_extents (cr, text, extents);
|
||||
cairo_show_glyphs (cr, &cairo_glyph, 1);
|
||||
cairo_glyph_extents (cr, &cairo_glyph, 1, extents);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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_bool_t *backward)
|
||||
{
|
||||
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,
|
||||
backward);
|
||||
}
|
||||
|
||||
static cairo_font_face_t *user_font_face = NULL;
|
||||
|
||||
static cairo_font_face_t *
|
||||
|
|
@ -99,6 +127,7 @@ get_user_font_face (void)
|
|||
user_font_face = cairo_user_font_face_create ();
|
||||
cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init);
|
||||
cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph);
|
||||
cairo_user_font_face_set_text_to_glyphs_func (user_font_face, test_scaled_font_text_to_glyphs);
|
||||
|
||||
/* This also happens to be default font face on cairo_t, so does
|
||||
* not make much sense here. For demonstration only.
|
||||
|
|
@ -108,9 +137,9 @@ get_user_font_face (void)
|
|||
CAIRO_FONT_WEIGHT_NORMAL);
|
||||
|
||||
cairo_font_face_set_user_data (user_font_face,
|
||||
&fallback_font_face_key,
|
||||
&fallback_font_key,
|
||||
fallback_font_face,
|
||||
cairo_font_face_destroy);
|
||||
(cairo_destroy_func_t) cairo_font_face_destroy);
|
||||
}
|
||||
|
||||
return user_font_face;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue