⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-font-subset.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 2 页
字号:
    u.bytes = malloc (size);    if (u.bytes == NULL) {	font->status = CAIRO_STATUS_NO_MEMORY;	return font->status;    }    FT_Load_Sfnt_Table (font->face, TTAG_loca, 0, u.bytes, &size);    start_offset = _cairo_array_num_elements (&font->output);    for (i = 0; i < font->base.num_glyphs; i++) {	index = font->glyphs[i].parent_index;	if (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]);	}	size = end - begin;	font->glyphs[i].location =	    cairo_pdf_ft_font_align_output (font) - start_offset;	status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);	if (status)	    break;        if (size != 0) {            FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size);            cairo_pdf_ft_font_remap_composite_glyph (font, buffer);        }    }    font->glyphs[i].location =	cairo_pdf_ft_font_align_output (font) - start_offset;    free (u.bytes);    return font->status;}static intcairo_pdf_ft_font_write_head_table (cairo_pdf_ft_font_t *font,				    unsigned long tag){    TT_Header *head;    head = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);    cairo_pdf_ft_font_write_be32 (font, head->Table_Version);    cairo_pdf_ft_font_write_be32 (font, head->Font_Revision);    font->checksum_index = _cairo_array_num_elements (&font->output);    cairo_pdf_ft_font_write_be32 (font, 0);    cairo_pdf_ft_font_write_be32 (font, head->Magic_Number);    cairo_pdf_ft_font_write_be16 (font, head->Flags);    cairo_pdf_ft_font_write_be16 (font, head->Units_Per_EM);    cairo_pdf_ft_font_write_be32 (font, head->Created[0]);    cairo_pdf_ft_font_write_be32 (font, head->Created[1]);    cairo_pdf_ft_font_write_be32 (font, head->Modified[0]);    cairo_pdf_ft_font_write_be32 (font, head->Modified[1]);    cairo_pdf_ft_font_write_be16 (font, head->xMin);    cairo_pdf_ft_font_write_be16 (font, head->yMin);    cairo_pdf_ft_font_write_be16 (font, head->xMax);    cairo_pdf_ft_font_write_be16 (font, head->yMax);    cairo_pdf_ft_font_write_be16 (font, head->Mac_Style);    cairo_pdf_ft_font_write_be16 (font, head->Lowest_Rec_PPEM);    cairo_pdf_ft_font_write_be16 (font, head->Font_Direction);    cairo_pdf_ft_font_write_be16 (font, head->Index_To_Loc_Format);    cairo_pdf_ft_font_write_be16 (font, head->Glyph_Data_Format);    return font->status;}static int cairo_pdf_ft_font_write_hhea_table (cairo_pdf_ft_font_t *font, unsigned long tag){    TT_HoriHeader *hhea;    hhea = FT_Get_Sfnt_Table (font->face, ft_sfnt_hhea);    cairo_pdf_ft_font_write_be32 (font, hhea->Version);    cairo_pdf_ft_font_write_be16 (font, hhea->Ascender);    cairo_pdf_ft_font_write_be16 (font, hhea->Descender);    cairo_pdf_ft_font_write_be16 (font, hhea->Line_Gap);    cairo_pdf_ft_font_write_be16 (font, hhea->advance_Width_Max);    cairo_pdf_ft_font_write_be16 (font, hhea->min_Left_Side_Bearing);    cairo_pdf_ft_font_write_be16 (font, hhea->min_Right_Side_Bearing);    cairo_pdf_ft_font_write_be16 (font, hhea->xMax_Extent);    cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Rise);    cairo_pdf_ft_font_write_be16 (font, hhea->caret_Slope_Run);    cairo_pdf_ft_font_write_be16 (font, hhea->caret_Offset);    cairo_pdf_ft_font_write_be16 (font, 0);    cairo_pdf_ft_font_write_be16 (font, 0);    cairo_pdf_ft_font_write_be16 (font, 0);    cairo_pdf_ft_font_write_be16 (font, 0);    cairo_pdf_ft_font_write_be16 (font, hhea->metric_Data_Format);    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);    return font->status;}static intcairo_pdf_ft_font_write_hmtx_table (cairo_pdf_ft_font_t *font,				    unsigned long tag){    cairo_status_t status;    unsigned long entry_size;    short *p;    int i;    for (i = 0; i < font->base.num_glyphs; i++) {	entry_size = 2 * sizeof (short);	status = cairo_pdf_ft_font_allocate_write_buffer (font, entry_size,							  (unsigned char **) &p);	/* XXX: Need to check status here. */	FT_Load_Sfnt_Table (font->face, TTAG_hmtx,			    font->glyphs[i].parent_index * entry_size,			    (FT_Byte *) p, &entry_size);	font->base.widths[i] = be16_to_cpu (p[0]);    }    return font->status;}static intcairo_pdf_ft_font_write_loca_table (cairo_pdf_ft_font_t *font,				    unsigned long tag){    int i;    TT_Header *header;    header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);    if (header->Index_To_Loc_Format == 0) {	for (i = 0; i < font->base.num_glyphs + 1; i++)	    cairo_pdf_ft_font_write_be16 (font, font->glyphs[i].location / 2);    }    else {	for (i = 0; i < font->base.num_glyphs + 1; i++)	    cairo_pdf_ft_font_write_be32 (font, font->glyphs[i].location);    }    return font->status;}static intcairo_pdf_ft_font_write_maxp_table (cairo_pdf_ft_font_t *font,				    unsigned long tag){    TT_MaxProfile *maxp;    maxp = FT_Get_Sfnt_Table (font->face, ft_sfnt_maxp);    cairo_pdf_ft_font_write_be32 (font, maxp->version);    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs);    cairo_pdf_ft_font_write_be16 (font, maxp->maxPoints);    cairo_pdf_ft_font_write_be16 (font, maxp->maxContours);    cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositePoints);    cairo_pdf_ft_font_write_be16 (font, maxp->maxCompositeContours);    cairo_pdf_ft_font_write_be16 (font, maxp->maxZones);    cairo_pdf_ft_font_write_be16 (font, maxp->maxTwilightPoints);    cairo_pdf_ft_font_write_be16 (font, maxp->maxStorage);    cairo_pdf_ft_font_write_be16 (font, maxp->maxFunctionDefs);    cairo_pdf_ft_font_write_be16 (font, maxp->maxInstructionDefs);    cairo_pdf_ft_font_write_be16 (font, maxp->maxStackElements);    cairo_pdf_ft_font_write_be16 (font, maxp->maxSizeOfInstructions);    cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentElements);    cairo_pdf_ft_font_write_be16 (font, maxp->maxComponentDepth);    return font->status;}typedef struct table table_t;struct table {    unsigned long tag;    int (*write) (cairo_pdf_ft_font_t *font, unsigned long tag);};static const table_t truetype_tables[] = {    /* As we write out the glyf table we remap composite glyphs.     * Remapping composite glyphs will reference the sub glyphs the     * composite glyph is made up of.  That needs to be done first so     * we have all the glyphs in the subset before going further. */    { TTAG_glyf, cairo_pdf_ft_font_write_glyf_table },    { TTAG_cmap, cairo_pdf_ft_font_write_cmap_table },    { TTAG_cvt,  cairo_pdf_ft_font_write_generic_table },    { TTAG_fpgm, cairo_pdf_ft_font_write_generic_table },    { TTAG_head, cairo_pdf_ft_font_write_head_table },    { TTAG_hhea, cairo_pdf_ft_font_write_hhea_table },    { TTAG_hmtx, cairo_pdf_ft_font_write_hmtx_table },    { TTAG_loca, cairo_pdf_ft_font_write_loca_table },    { TTAG_maxp, cairo_pdf_ft_font_write_maxp_table },    { TTAG_name, cairo_pdf_ft_font_write_generic_table },    { TTAG_prep, cairo_pdf_ft_font_write_generic_table },};static cairo_status_tcairo_pdf_ft_font_write_offset_table (cairo_pdf_ft_font_t *font){    cairo_status_t status;    unsigned char *table_buffer;    size_t table_buffer_length;    unsigned short search_range, entry_selector, range_shift;    int num_tables;    num_tables = ARRAY_LENGTH (truetype_tables);    search_range = 1;    entry_selector = 0;    while (search_range * 2 <= num_tables) {	search_range *= 2;	entry_selector++;    }    search_range *= 16;    range_shift = num_tables * 16 - search_range;    cairo_pdf_ft_font_write_be32 (font, SFNT_VERSION);    cairo_pdf_ft_font_write_be16 (font, num_tables);    cairo_pdf_ft_font_write_be16 (font, search_range);    cairo_pdf_ft_font_write_be16 (font, entry_selector);    cairo_pdf_ft_font_write_be16 (font, range_shift);    /* XXX: Why are we allocating a table here and then ignoring the     * returned buffer? This should result in garbage in the output     * file, correct? Is this just unfinished code? -cworth. */    table_buffer_length = ARRAY_LENGTH (truetype_tables) * 16;    status = cairo_pdf_ft_font_allocate_write_buffer (font, table_buffer_length,						      &table_buffer);    if (status)	return status;    return font->status;}static unsigned longcairo_pdf_ft_font_calculate_checksum (cairo_pdf_ft_font_t *font,			   unsigned long start, unsigned long end){    unsigned long *padded_end;    unsigned long *p;    unsigned long checksum;    char *data;    checksum = 0;    data = _cairo_array_index (&font->output, 0);    p = (unsigned long *) (data + start);    padded_end = (unsigned long *) (data + ((end + 3) & ~3));    while (p < padded_end)	checksum += *p++;    return checksum;}static voidcairo_pdf_ft_font_update_entry (cairo_pdf_ft_font_t *font, int index, unsigned long tag,			unsigned long start, unsigned long end){    unsigned long *entry;    entry = _cairo_array_index (&font->output, 12 + 16 * index);    entry[0] = cpu_to_be32 (tag);    entry[1] = cpu_to_be32 (cairo_pdf_ft_font_calculate_checksum (font, start, end));    entry[2] = cpu_to_be32 (start);    entry[3] = cpu_to_be32 (end - start);}static cairo_status_tcairo_pdf_ft_font_generate (void *abstract_font,			    const char **data, unsigned long *length){    cairo_ft_unscaled_font_t *ft_unscaled_font;    cairo_pdf_ft_font_t *font = abstract_font;    unsigned long start, end, next, checksum, *checksum_location;    int i;    /* XXX: It would be cleaner to do something besides this cast     * here. Perhaps cairo_pdf_ft_font_t should just have the     * cairo_ft_unscaled_font_t rather than having the generic     * cairo_unscaled_font_t in the base class? */    ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font;    font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);    if (cairo_pdf_ft_font_write_offset_table (font))	goto fail;    start = cairo_pdf_ft_font_align_output (font);    end = start;    end = 0;    for (i = 0; i < ARRAY_LENGTH (truetype_tables); i++) {	if (truetype_tables[i].write (font, truetype_tables[i].tag))	    goto fail;	end = _cairo_array_num_elements (&font->output);	next = cairo_pdf_ft_font_align_output (font);	cairo_pdf_ft_font_update_entry (font, i, truetype_tables[i].tag,					start, end);	start = next;    }    checksum =	0xb1b0afba - cairo_pdf_ft_font_calculate_checksum (font, 0, end);    checksum_location = _cairo_array_index (&font->output, font->checksum_index);    *checksum_location = cpu_to_be32 (checksum);    *data = _cairo_array_index (&font->output, 0);    *length = _cairo_array_num_elements (&font->output); fail:    _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);    font->face = NULL;    return font->status;}static intcairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph){    if (font->parent_to_subset[glyph] == 0) {	font->parent_to_subset[glyph] = font->base.num_glyphs;	font->glyphs[font->base.num_glyphs].parent_index = glyph;	font->base.num_glyphs++;    }    return font->parent_to_subset[glyph];}cairo_status_t_cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,			     cairo_scaled_font_subset_t	*font_subset){    cairo_pdf_ft_font_t *font;    cairo_status_t status;    const char *data = NULL; /* squelch bogus compiler warning */    unsigned long parent_glyph, length = 0; /* squelch bogus compiler warning */    int i;    status = _cairo_pdf_ft_font_create (font_subset, &font);    if (status)	return status;    for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {	parent_glyph = font->scaled_font_subset->glyphs[i];	cairo_pdf_ft_font_use_glyph (font, parent_glyph);    }    status = cairo_pdf_ft_font_generate (font, &data, &length);    if (status)	goto fail1;    truetype_subset->base_font = strdup (font->base.base_font);    if (truetype_subset->base_font == NULL)	goto fail1;    truetype_subset->widths = calloc (sizeof (int), font->base.num_glyphs);    if (truetype_subset->widths == NULL)	goto fail2;    for (i = 0; i < font->base.num_glyphs; i++)	truetype_subset->widths[i] = font->base.widths[i];    truetype_subset->x_min = font->base.x_min;    truetype_subset->y_min = font->base.y_min;    truetype_subset->x_max = font->base.x_max;    truetype_subset->y_max = font->base.y_max;    truetype_subset->ascent = font->base.ascent;    truetype_subset->descent = font->base.descent;    truetype_subset->data = malloc (length);    if (truetype_subset->data == NULL)	goto fail3;    memcpy (truetype_subset->data, data, length);    truetype_subset->data_length = length;    cairo_pdf_ft_font_destroy (font);    return CAIRO_STATUS_SUCCESS; fail3:    free (truetype_subset->widths); fail2:    free (truetype_subset->base_font); fail1:    cairo_pdf_ft_font_destroy (font);    return status;}void_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset){    free (subset->base_font);    free (subset->widths);    free (subset->data);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -