示例#1
0
static cairo_status_t
cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
                                      unsigned long          tag)
{
    unsigned char *buffer;
    unsigned long size;
    cairo_status_t status;

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

    size = 0;
    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
						 tag, 0, NULL, &size);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
    status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
						 tag, 0, buffer, &size);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    /* set checkSumAdjustment to 0 for table checksum calcualtion */
    *(uint32_t *)(buffer + 8) = 0;

    return CAIRO_STATUS_SUCCESS;
}
示例#2
0
static cairo_status_t
cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
				      unsigned long          tag)
{
    tt_maxp_t *maxp;
    unsigned long size;
    cairo_status_t status;

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

    size = sizeof (tt_maxp_t);
    status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
						 tag, 0, (unsigned char *) maxp, &size);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);

    return CAIRO_STATUS_SUCCESS;
}
示例#3
0
static cairo_status_t
cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
					 unsigned long          tag)
{
    cairo_status_t status;
    unsigned char *buffer;
    unsigned long size;

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

    size = 0;
    status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font,
					        tag, 0, NULL, &size);
    if (unlikely (status))
        return _cairo_truetype_font_set_error (font, status);

    status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
						 tag, 0, buffer, &size);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    return CAIRO_STATUS_SUCCESS;
}
示例#4
0
static cairo_status_t
cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
{
    cairo_status_t status;
    unsigned char *table_buffer;
    size_t table_buffer_length;
    unsigned short search_range, entry_selector, range_shift;

    search_range = 1;
    entry_selector = 0;
    while (search_range * 2 <= font->num_tables) {
	search_range *= 2;
	entry_selector++;
    }
    search_range *= 16;
    range_shift = font->num_tables * 16 - search_range;

    cairo_truetype_font_write_be32 (font, SFNT_VERSION);
    cairo_truetype_font_write_be16 (font, font->num_tables);
    cairo_truetype_font_write_be16 (font, search_range);
    cairo_truetype_font_write_be16 (font, entry_selector);
    cairo_truetype_font_write_be16 (font, range_shift);

    /* Allocate space for the table directory. Each directory entry
     * will be filled in by cairo_truetype_font_update_entry() after
     * the table is written. */
    table_buffer_length = font->num_tables * 16;
    status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
						      &table_buffer);
    if (status)
	return status;

    return font->status;
}
示例#5
0
static cairo_status_t
cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
				      unsigned long          tag)
{
    unsigned long size;
    unsigned long long_entry_size;
    unsigned long short_entry_size;
    short *p;
    unsigned int i;
    tt_hhea_t hhea;
    int num_hmetrics;

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

    num_hmetrics = be16_to_cpu(hhea.num_hmetrics);

    for (i = 0; i < font->base.num_glyphs; i++) {
        long_entry_size = 2 * sizeof (int16_t);
        short_entry_size = sizeof (int16_t);
        font->status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size,
								  (unsigned char **) &p);
	if (font->status)
	    return font->status;

        if (font->glyphs[i].parent_index < num_hmetrics) {
            if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                                    TT_TAG_hmtx,
                                                    font->glyphs[i].parent_index * long_entry_size,
                                                    (unsigned char *) p, &long_entry_size) != CAIRO_STATUS_SUCCESS) {
                font->status = CAIRO_INT_STATUS_UNSUPPORTED;
                return font->status;
            }
        }
        else
        {
            if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                                    TT_TAG_hmtx,
                                                    (num_hmetrics - 1) * long_entry_size,
                                                    (unsigned char *) p, &short_entry_size) != CAIRO_STATUS_SUCCESS) {
                font->status = CAIRO_INT_STATUS_UNSUPPORTED;
                return font->status;
            }
            font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
							       TT_TAG_hmtx,
							       num_hmetrics * long_entry_size +
							       (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
							       (unsigned char *) (p + 1), &short_entry_size);
	    if (font->status)
		return font->status;
        }
        font->base.widths[i] = be16_to_cpu (p[0]);
    }

    return font->status;
}
示例#6
0
static cairo_status_t
cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
					 unsigned long          tag)
{
    cairo_status_t status;
    unsigned char *buffer;
    unsigned long size;

    size = 0;
    if (font->backend->load_truetype_table( font->scaled_font_subset->scaled_font,
					    tag, 0, NULL, &size) != CAIRO_STATUS_SUCCESS) {
        font->status = CAIRO_INT_STATUS_UNSUPPORTED;
        return font->status;
    }

    status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
    if (status)
	return status;

    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
						 tag, 0, buffer, &size);
    if (status)
	return status;

    return CAIRO_STATUS_SUCCESS;
}
示例#7
0
static unsigned long
cairo_truetype_font_align_output (cairo_truetype_font_t *font)
{
    int length, aligned, pad;
    unsigned char *padding;

    length = _cairo_array_num_elements (&font->output);
    aligned = (length + 3) & ~3;
    pad = aligned - length;

    if (pad) {
	cairo_truetype_font_allocate_write_buffer (font, pad, &padding);
	memset (padding, 0, pad);
    }

    return aligned;
}
示例#8
0
static cairo_status_t
cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag)
{
    tt_hhea_t *hhea;
    unsigned long size;

    size = sizeof (tt_hhea_t);
    font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
    if (font->status)
	return font->status;

    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
						       tag, 0, (unsigned char *) hhea, &size);
    if (font->status)
	return font->status;

    hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));

    return font->status;
}
示例#9
0
static cairo_status_t
cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
				      unsigned long          tag)
{
    tt_maxp_t *maxp;
    unsigned long size;

    size = sizeof (tt_maxp_t);
    font->status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
    if (font->status)
	return font->status;

    font->status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
						       tag, 0, (unsigned char *) maxp, &size);
    if (font->status)
	return font->status;

    maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);

    return font->status;
}
示例#10
0
static cairo_status_t
cairo_truetype_font_align_output (cairo_truetype_font_t	    *font,
	                          unsigned long		    *aligned)
{
    int length, pad;
    unsigned char *padding;

    length = _cairo_array_num_elements (&font->output);
    *aligned = (length + 3) & ~3;
    pad = *aligned - length;

    if (pad) {
	cairo_status_t status;

	status = cairo_truetype_font_allocate_write_buffer (font, pad,
		                                            &padding);
	if (unlikely (status))
	    return status;

	memset (padding, 0, pad);
    }

    return CAIRO_STATUS_SUCCESS;
}
示例#11
0
static cairo_status_t
cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
				      unsigned long          tag)
{
    unsigned long start_offset, index, size, next;
    tt_head_t header;
    unsigned long begin, end;
    unsigned char *buffer;
    unsigned int i;
    union {
	unsigned char *bytes;
	uint16_t      *short_offsets;
	uint32_t      *long_offsets;
    } u;
    cairo_status_t status;

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

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

    if (be16_to_cpu (header.index_to_loc_format) == 0)
	size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
    else
	size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);

    u.bytes = malloc (size);
    if (unlikely (u.bytes == NULL))
	return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);

    status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
                                                 TT_TAG_loca, 0, u.bytes, &size);
    if (unlikely (status))
	return _cairo_truetype_font_set_error (font, status);

    start_offset = _cairo_array_num_elements (&font->output);
    for (i = 0; i < font->base.num_glyphs; i++) {
	index = font->glyphs[i].parent_index;
	if (be16_to_cpu (header.index_to_loc_format) == 0) {
	    begin = be16_to_cpu (u.short_offsets[index]) * 2;
	    end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
	}
	else {
	    begin = be32_to_cpu (u.long_offsets[index]);
	    end = be32_to_cpu (u.long_offsets[index + 1]);
	}

	/* quick sanity check... */
	if (end < begin) {
	    status = CAIRO_INT_STATUS_UNSUPPORTED;
	    goto FAIL;
	}

	size = end - begin;
        status = cairo_truetype_font_align_output (font, &next);
	if (unlikely (status))
	    goto FAIL;

        status = cairo_truetype_font_check_boundary (font, next);
	if (unlikely (status))
	    goto FAIL;

        font->glyphs[i].location = next - start_offset;

	status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
	if (unlikely (status))
	    goto FAIL;

        if (size != 0) {
            status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
							 TT_TAG_glyf, begin, buffer, &size);
	    if (unlikely (status))
		goto FAIL;

            status = cairo_truetype_font_remap_composite_glyph (font, buffer, size);
	    if (unlikely (status))
		goto FAIL;
        }
    }

    status = cairo_truetype_font_align_output (font, &next);
    if (unlikely (status))
	goto FAIL;

    font->glyphs[i].location = next - start_offset;

    status = font->status;
FAIL:
    free (u.bytes);

    return _cairo_truetype_font_set_error (font, status);
}