Ejemplo n.º 1
0
static void
cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
					   unsigned char         *buffer)
{
    tt_glyph_data_t *glyph_data;
    tt_composite_glyph_t *composite_glyph;
    int num_args;
    int has_more_components;
    unsigned short flags;
    unsigned short index;

    glyph_data = (tt_glyph_data_t *) buffer;
    if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
        return;

    composite_glyph = &glyph_data->glyph;
    do {
        flags = be16_to_cpu (composite_glyph->flags);
        has_more_components = flags & TT_MORE_COMPONENTS;
        index = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
        composite_glyph->index = cpu_to_be16 (index);
        num_args = 1;
        if (flags & TT_ARG_1_AND_2_ARE_WORDS)
            num_args += 1;
        if (flags & TT_WE_HAVE_A_SCALE)
            num_args += 1;
        else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
            num_args += 2;
        else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
            num_args += 3;
        composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
    } while (has_more_components);
}
Ejemplo n.º 2
0
static cairo_status_t
cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t	*font,
					   unsigned char		*buffer,
					   unsigned long		 size)
{
    tt_glyph_data_t *glyph_data;
    tt_composite_glyph_t *composite_glyph;
    int num_args;
    int has_more_components;
    unsigned short flags;
    unsigned short index;
    cairo_status_t status;
    unsigned char *end = buffer + size;

    if (font->status)
	return font->status;

    glyph_data = (tt_glyph_data_t *) buffer;
    if ((unsigned char *)(&glyph_data->data) >= end)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
        return CAIRO_STATUS_SUCCESS;

    composite_glyph = &glyph_data->glyph;
    do {
	if ((unsigned char *)(&composite_glyph->args[1]) > end)
	    return CAIRO_INT_STATUS_UNSUPPORTED;

	flags = be16_to_cpu (composite_glyph->flags);
        has_more_components = flags & TT_MORE_COMPONENTS;
        status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
	if (unlikely (status))
	    return status;

        composite_glyph->index = cpu_to_be16 (index);
        num_args = 1;
        if (flags & TT_ARG_1_AND_2_ARE_WORDS)
            num_args += 1;

	if (flags & TT_WE_HAVE_A_SCALE)
            num_args += 1;
        else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
            num_args += 2;
        else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
            num_args += 4;

	composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
    } while (has_more_components);

    return CAIRO_STATUS_SUCCESS;
}
Ejemplo n.º 3
0
cairo_status_t
_cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
			     cairo_scaled_font_subset_t	*font_subset)
{
    cairo_truetype_font_t *font = NULL;
    cairo_status_t status;
    const char *data = NULL; /* squelch bogus compiler warning */
    unsigned long length = 0; /* squelch bogus compiler warning */
    unsigned long offsets_length;
    unsigned int i;
    const unsigned long *string_offsets = NULL;
    unsigned long num_strings = 0;

    status = _cairo_truetype_font_create (font_subset, &font);
    if (unlikely (status))
	return status;

    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
	unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
	status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
	if (unlikely (status))
	    goto fail1;
    }

    cairo_truetype_font_create_truetype_table_list (font);
    status = cairo_truetype_font_generate (font, &data, &length,
                                           &string_offsets, &num_strings);
    if (unlikely (status))
	goto fail1;

    truetype_subset->ps_name = strdup (font->base.ps_name);
    if (unlikely (truetype_subset->ps_name == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto fail1;
    }

    if (font->base.font_name != NULL) {
	truetype_subset->font_name = strdup (font->base.font_name);
	if (unlikely (truetype_subset->font_name == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto fail2;
	}
    } else {
	truetype_subset->font_name = NULL;
    }

    /* The widths array returned must contain only widths for the
     * glyphs in font_subset. Any subglyphs appended after
     * font_subset->num_glyphs are omitted. */
    truetype_subset->widths = calloc (sizeof (double),
                                      font->scaled_font_subset->num_glyphs);
    if (unlikely (truetype_subset->widths == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto fail3;
    }
    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
	truetype_subset->widths[i] = (double)font->base.widths[i]/font->base.units_per_em;

    truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em;
    truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em;
    truetype_subset->x_max = (double)font->base.x_max/font->base.units_per_em;
    truetype_subset->y_max = (double)font->base.y_max/font->base.units_per_em;
    truetype_subset->ascent = (double)font->base.ascent/font->base.units_per_em;
    truetype_subset->descent = (double)font->base.descent/font->base.units_per_em;

    if (length) {
	truetype_subset->data = malloc (length);
	if (unlikely (truetype_subset->data == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto fail4;
	}

	memcpy (truetype_subset->data, data, length);
    } else
	truetype_subset->data = NULL;
    truetype_subset->data_length = length;

    if (num_strings) {
	offsets_length = num_strings * sizeof (unsigned long);
	truetype_subset->string_offsets = malloc (offsets_length);
	if (unlikely (truetype_subset->string_offsets == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto fail5;
	}

	memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
	truetype_subset->num_string_offsets = num_strings;
    } else {
	truetype_subset->string_offsets = NULL;
	truetype_subset->num_string_offsets = 0;
    }

    cairo_truetype_font_destroy (font);

    return CAIRO_STATUS_SUCCESS;

 fail5:
    free (truetype_subset->data);
 fail4:
    free (truetype_subset->widths);
 fail3:
    if (truetype_subset->font_name)
	free (truetype_subset->font_name);
 fail2:
    free (truetype_subset->ps_name);
 fail1:
    cairo_truetype_font_destroy (font);

    return status;
}