コード例 #1
0
ファイル: cairo-array.c プロジェクト: 1833183060/wke
/**
 * _cairo_array_allocate:
 * @array: a #cairo_array_t
 *
 * Allocate space at the end of the array for @num_elements additional
 * elements, providing the address of the new memory chunk in
 * @elements. This memory will be unitialized, but will be accounted
 * for in the return value of _cairo_array_num_elements().
 *
 * Return value: %CAIRO_STATUS_SUCCESS if successful or
 * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
 * operation.
 **/
cairo_status_t
_cairo_array_allocate (cairo_array_t	 *array,
		       unsigned int	  num_elements,
		       void		**elements)
{
    cairo_status_t status;

    status = _cairo_array_grow_by (array, num_elements);
    if (unlikely (status))
	return status;

    assert (array->num_elements + num_elements <= array->size);

    *elements = array->elements + array->num_elements * array->element_size;

    array->num_elements += num_elements;

    return CAIRO_STATUS_SUCCESS;
}
コード例 #2
0
ファイル: cairo-array.c プロジェクト: soubok/libset
/**
 * _cairo_array_allocate:
 *
 * Allocate space at the end of the array for @num_elements additional
 * elements, providing the address of the new memory chunk in
 * @elements. This memory will be unitialized, but will be accounted
 * for in the return value of _cairo_array_num_elements().
 *
 * Return value: %CAIRO_STATUS_SUCCESS if successful or
 * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the
 * operation.
 **/
cairo_status_t
_cairo_array_allocate (cairo_array_t	 *array,
		       unsigned int	  num_elements,
		       void		**elements)
{
    cairo_status_t status;

    assert (! array->is_snapshot);

    status = _cairo_array_grow_by (array, num_elements);
    if (status)
	return status;

    assert (array->num_elements + num_elements <= array->size);

    *elements = &(*array->elements)[array->num_elements * array->element_size];

    array->num_elements += num_elements;

    return CAIRO_STATUS_SUCCESS;
}
コード例 #3
0
static cairo_status_t
_cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
			     cairo_truetype_font_t      **font_return)
{
    cairo_status_t status;
    cairo_truetype_font_t *font;
    const cairo_scaled_font_backend_t *backend;
    tt_head_t head;
    tt_hhea_t hhea;
    tt_maxp_t maxp;
    unsigned long size;

    backend = scaled_font_subset->scaled_font->backend;
    if (!backend->load_truetype_table)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    /* FIXME: We should either support subsetting vertical fonts, or fail on
     * vertical.  Currently font_options_t doesn't have vertical flag, but
     * it should be added in the future.  For now, the freetype backend
     * returns UNSUPPORTED in load_truetype_table if the font is vertical.
     *
     *  if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
     *   return CAIRO_INT_STATUS_UNSUPPORTED;
     */

    size = sizeof (tt_head_t);
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
                                          TT_TAG_head, 0,
					  (unsigned char *) &head,
                                          &size);
    if (unlikely (status))
	return status;

    size = sizeof (tt_maxp_t);
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
                                           TT_TAG_maxp, 0,
					   (unsigned char *) &maxp,
					   &size);
    if (unlikely (status))
	return status;

    size = sizeof (tt_hhea_t);
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
                                           TT_TAG_hhea, 0,
					   (unsigned char *) &hhea,
					   &size);
    if (unlikely (status))
	return status;

    font = malloc (sizeof (cairo_truetype_font_t));
    if (unlikely (font == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    font->backend = backend;
    font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
    font->scaled_font_subset = scaled_font_subset;

    font->last_offset = 0;
    font->last_boundary = 0;
    _cairo_array_init (&font->output, sizeof (char));
    status = _cairo_array_grow_by (&font->output, 4096);
    if (unlikely (status))
	goto fail1;

    font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
    if (unlikely (font->glyphs == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto fail1;
    }

    font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
    if (unlikely (font->parent_to_subset == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto fail2;
    }

    font->base.num_glyphs = 0;
    font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
    font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
    font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
    font->base.y_max = (int16_t) be16_to_cpu (head.y_max);
    font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender);
    font->base.descent = (int16_t) be16_to_cpu (hhea.descender);
    font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
    if (font->base.units_per_em == 0)
        font->base.units_per_em = 2048;

    font->base.font_name = NULL;
    status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
					     &font->base.ps_name,
					     &font->base.font_name);
    if (_cairo_status_is_error (status))
	goto fail3;

    /* If the PS name is not found, create a CairoFont-x-y name. */
    if (font->base.ps_name == NULL) {
        font->base.ps_name = malloc (30);
        if (unlikely (font->base.ps_name == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
            goto fail3;
	}

        snprintf(font->base.ps_name, 30, "CairoFont-%u-%u",
                 scaled_font_subset->font_id,
                 scaled_font_subset->subset_id);
    }

    font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
    if (unlikely (font->base.widths == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto fail4;
    }

    _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
    status = _cairo_array_grow_by (&font->string_offsets, 10);
    if (unlikely (status))
	goto fail5;

    font->status = CAIRO_STATUS_SUCCESS;

    *font_return = font;

    return CAIRO_STATUS_SUCCESS;

 fail5:
    _cairo_array_fini (&font->string_offsets);
    free (font->base.widths);
 fail4:
    free (font->base.ps_name);
 fail3:
    free (font->parent_to_subset);
    if (font->base.font_name)
	free (font->base.font_name);
 fail2:
    free (font->glyphs);
 fail1:
    _cairo_array_fini (&font->output);
    free (font);

    return status;
}
コード例 #4
0
static cairo_status_t
_cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
			     cairo_truetype_font_t      **font_return)
{
    cairo_status_t status;
    cairo_truetype_font_t *font;
    const cairo_scaled_font_backend_t *backend;
    tt_head_t head;
    tt_hhea_t hhea;
    tt_maxp_t maxp;
    tt_name_t *name;
    tt_name_record_t *record;
    unsigned long size;
    int i, j;

    backend = scaled_font_subset->scaled_font->backend;
    if (!backend->load_truetype_table)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    /* FIXME: We should either support subsetting vertical fonts, or fail on
     * vertical.  Currently font_options_t doesn't have vertical flag, but
     * it should be added in the future.  For now, the freetype backend
     * returns UNSUPPORTED in load_truetype_table if the font is vertical.
     *
     *  if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
     *   return CAIRO_INT_STATUS_UNSUPPORTED;
     */

    size = sizeof (tt_head_t);
    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
                                      TT_TAG_head, 0, (unsigned char *) &head,
                                      &size) != CAIRO_STATUS_SUCCESS)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    size = sizeof (tt_maxp_t);
    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
                                      TT_TAG_maxp, 0, (unsigned char *) &maxp,
                                      &size) != CAIRO_STATUS_SUCCESS)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    size = sizeof (tt_hhea_t);
    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
                                      TT_TAG_hhea, 0, (unsigned char *) &hhea,
                                      &size) != CAIRO_STATUS_SUCCESS)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    size = 0;
    if (backend->load_truetype_table (scaled_font_subset->scaled_font,
                                      TT_TAG_name, 0, NULL,
                                      &size) != CAIRO_STATUS_SUCCESS)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    name = malloc(size);
    if (name == NULL)
        return CAIRO_STATUS_NO_MEMORY;

    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
					   TT_TAG_name, 0, (unsigned char *) name,
					   &size);
    if (status)
	goto fail0;

    font = malloc (sizeof (cairo_truetype_font_t));
    if (font == NULL) {
	status = CAIRO_STATUS_NO_MEMORY;
	goto fail0;
    }

    font->backend = backend;
    font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
    font->scaled_font_subset = scaled_font_subset;

    font->last_offset = 0;
    font->last_boundary = 0;
    _cairo_array_init (&font->output, sizeof (char));
    status = _cairo_array_grow_by (&font->output, 4096);
    if (status)
	goto fail1;

    font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
    if (font->glyphs == NULL) {
	status = CAIRO_STATUS_NO_MEMORY;
	goto fail1;
    }

    font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
    if (font->parent_to_subset == NULL) {
	status = CAIRO_STATUS_NO_MEMORY;
	goto fail2;
    }

    font->base.num_glyphs = 0;
    font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
    font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
    font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
    font->base.y_max = (int16_t) be16_to_cpu (head.y_max);
    font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender);
    font->base.descent = (int16_t) be16_to_cpu (hhea.descender);
    font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
    if (font->base.units_per_em == 0)
        font->base.units_per_em = 2048;

    /* Extract the font name from the name table. At present this
     * just looks for the Mac platform/Roman encoded font name. It
     * should be extended to use any suitable font name in the
     * name table. If the mac/roman font name is not found a
     * CairoFont-x-y name is created.
     */
    font->base.base_font = NULL;
    for (i = 0; i < be16_to_cpu(name->num_records); i++) {
        record = &(name->records[i]);
        if ((be16_to_cpu (record->platform) == 1) &&
            (be16_to_cpu (record->encoding) == 0) &&
            (be16_to_cpu (record->name) == 4)) { 
            font->base.base_font = malloc (be16_to_cpu(record->length) + 1);
            if (font->base.base_font) {
                strncpy(font->base.base_font,
                        ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
                        be16_to_cpu (record->length));
                font->base.base_font[be16_to_cpu (record->length)] = 0;
            }
            break;
        }
    }

    free (name);
    name = NULL;

    if (font->base.base_font == NULL) {
        font->base.base_font = malloc (30);
        if (font->base.base_font == NULL) {
	    status = CAIRO_STATUS_NO_MEMORY;
            goto fail3;
	}

        snprintf(font->base.base_font, 30, "CairoFont-%u-%u",
                 scaled_font_subset->font_id,
                 scaled_font_subset->subset_id);
    }

    for (i = 0, j = 0; font->base.base_font[j]; j++) {
	if (font->base.base_font[j] == ' ')
	    continue;
	font->base.base_font[i++] = font->base.base_font[j];
    }
    font->base.base_font[i] = '\0';

    font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
    if (font->base.widths == NULL) {
	status = CAIRO_STATUS_NO_MEMORY;
	goto fail4;
    }

    _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
    status = _cairo_array_grow_by (&font->string_offsets, 10);
    if (status)
	goto fail5;

    font->status = CAIRO_STATUS_SUCCESS;

    *font_return = font;

    return CAIRO_STATUS_SUCCESS;

 fail5:
    _cairo_array_fini (&font->string_offsets);
    free (font->base.widths);
 fail4:
    free (font->base.base_font);
 fail3:
    free (font->parent_to_subset);
 fail2:
    free (font->glyphs);
 fail1:
    _cairo_array_fini (&font->output);
    free (font);
 fail0:
    if (name)
	free (name);

    return status;
}