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

📄 cairo-font-subset.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 2 页
字号:
/* cairo - a vector graphics library with display and print output * * Copyright © 2004 Red Hat, Inc * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * (the "LGPL") or, at your option, under the terms of the Mozilla * Public License Version 1.1 (the "MPL"). If you do not alter this * notice, a recipient may use your version of this file under either * the MPL or the LGPL. * * You should have received a copy of the LGPL along with this library * in the file COPYING-LGPL-2.1; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * You should have received a copy of the MPL along with this library * in the file COPYING-MPL-1.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY * OF ANY KIND, either express or implied. See the LGPL or the MPL for * the specific language governing rights and limitations. * * The Original Code is the cairo graphics library. * * The Initial Developer of the Original Code is Red Hat, Inc. * * Contributor(s): *	Kristian Høgsberg <krh@redhat.com> */#include "cairoint.h"#include "cairo-scaled-font-subsets-private.h"/* XXX: Eventually, we need to handle other font backends */#include "cairo-ft-private.h"#include <ft2build.h>#include FT_FREETYPE_H#include FT_OUTLINE_H#include FT_TRUETYPE_TAGS_H#include FT_TRUETYPE_TABLES_Htypedef struct ft_subset_glyph ft_subset_glyph_t;struct ft_subset_glyph {    int parent_index;    unsigned long location;};typedef struct _cairo_ft_font {    cairo_scaled_font_subset_t *scaled_font_subset;    struct {	cairo_unscaled_font_t *unscaled_font;	unsigned int font_id;	char *base_font;	int num_glyphs;	int *widths;	long x_min, y_min, x_max, y_max;	long ascent, descent;    } base;    ft_subset_glyph_t *glyphs;    FT_Face face;    int checksum_index;    cairo_array_t output;    int *parent_to_subset;    cairo_status_t status;} cairo_pdf_ft_font_t;static intcairo_pdf_ft_font_use_glyph (cairo_pdf_ft_font_t *font, int glyph);#define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) )#define SFNT_VERSION			0x00010000#ifdef WORDS_BIGENDIAN#define cpu_to_be16(v) (v)#define be16_to_cpu(v) (v)#define cpu_to_be32(v) (v)#define be32_to_cpu(v) (v)#elsestatic inline unsigned shortcpu_to_be16(unsigned short v){    return (v << 8) | (v >> 8);}static inline unsigned shortbe16_to_cpu(unsigned short v){    return cpu_to_be16 (v);}static inline unsigned longcpu_to_be32(unsigned long v){    return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);}static inline unsigned longbe32_to_cpu(unsigned long v){    return cpu_to_be32 (v);}#endifstatic cairo_status_t_cairo_pdf_ft_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,			   cairo_pdf_ft_font_t        **font_return){    cairo_unscaled_font_t *unscaled_font;    cairo_ft_unscaled_font_t *ft_unscaled_font;    cairo_status_t status = CAIRO_STATUS_NO_MEMORY;    cairo_pdf_ft_font_t *font;    FT_Face face;    unsigned long size;    int i, j;    /* XXX: Need to fix this to work with a general cairo_unscaled_font_t. */    if (!_cairo_scaled_font_is_ft (scaled_font_subset->scaled_font))	return CAIRO_INT_STATUS_UNSUPPORTED;    if (_cairo_ft_scaled_font_is_vertical (scaled_font_subset->scaled_font))	return CAIRO_INT_STATUS_UNSUPPORTED;        unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font);    ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font;    face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font);    if (face == NULL)	/* Assume out of memory */	return CAIRO_STATUS_NO_MEMORY;    /* We currently only support freetype truetype fonts. */    size = 0;    if (!FT_IS_SFNT (face) ||	FT_Load_Sfnt_Table (face, TTAG_glyf, 0, NULL, &size) != 0)	return CAIRO_INT_STATUS_UNSUPPORTED;    font = malloc (sizeof (cairo_pdf_ft_font_t));    if (font == NULL)	return CAIRO_STATUS_NO_MEMORY;    font->scaled_font_subset = scaled_font_subset;    font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);    _cairo_array_init (&font->output, sizeof (char));    if (_cairo_array_grow_by (&font->output, 4096) != CAIRO_STATUS_SUCCESS)	goto fail1;    font->glyphs = calloc (face->num_glyphs + 1, sizeof (ft_subset_glyph_t));    if (font->glyphs == NULL)	goto fail2;    font->parent_to_subset = calloc (face->num_glyphs, sizeof (int));    if (font->parent_to_subset == NULL)	goto fail3;    font->base.num_glyphs = 0;    font->base.x_min = face->bbox.xMin;    font->base.y_min = face->bbox.yMin;    font->base.x_max = face->bbox.xMax;    font->base.y_max = face->bbox.yMax;    font->base.ascent = face->ascender;    font->base.descent = face->descender;    font->base.base_font = strdup (face->family_name);    if (font->base.base_font == NULL)	goto fail4;    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 (face->num_glyphs, sizeof (int));    if (font->base.widths == NULL)	goto fail5;    _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font);    font->status = CAIRO_STATUS_SUCCESS;    *font_return = font;    return CAIRO_STATUS_SUCCESS; fail5:    free (font->base.base_font); fail4:    free (font->parent_to_subset); fail3:    free (font->glyphs); fail2:    _cairo_array_fini (&font->output); fail1:    free (font);    return status;}static voidcairo_pdf_ft_font_destroy (cairo_pdf_ft_font_t *font){    _cairo_unscaled_font_destroy (font->base.unscaled_font);    free (font->base.base_font);    free (font->parent_to_subset);    free (font->glyphs);    _cairo_array_fini (&font->output);    free (font);}static cairo_status_tcairo_pdf_ft_font_allocate_write_buffer (cairo_pdf_ft_font_t	 *font,					 size_t			  length,					 unsigned char		**buffer){    cairo_status_t status;    status = _cairo_array_allocate (&font->output, length, (void **) buffer);    if (status)	return status;    return CAIRO_STATUS_SUCCESS;}static cairo_status_tcairo_pdf_ft_font_write (cairo_pdf_ft_font_t *font,			 const void *data, size_t length){    cairo_status_t status;    status = _cairo_array_append_multiple (&font->output, data, length);    if (status)	return status;    return CAIRO_STATUS_SUCCESS;}static voidcairo_pdf_ft_font_write_be16 (cairo_pdf_ft_font_t *font,			      unsigned short value){    unsigned short be16_value;    be16_value = cpu_to_be16 (value);    cairo_pdf_ft_font_write (font, &be16_value, sizeof be16_value);}static voidcairo_pdf_ft_font_write_be32 (cairo_pdf_ft_font_t *font, unsigned long value){    unsigned long be32_value;    be32_value = cpu_to_be32 (value);    cairo_pdf_ft_font_write (font, &be32_value, sizeof be32_value);}static unsigned longcairo_pdf_ft_font_align_output (cairo_pdf_ft_font_t *font){    int length, aligned, pad;    unsigned char *ignored;    length = _cairo_array_num_elements (&font->output);    aligned = (length + 3) & ~3;    pad = aligned - length;    if (pad)	cairo_pdf_ft_font_allocate_write_buffer (font, pad, &ignored);    return aligned;}static intcairo_pdf_ft_font_write_cmap_table (cairo_pdf_ft_font_t *font, unsigned long tag){    int i;    cairo_pdf_ft_font_write_be16 (font, 0);    cairo_pdf_ft_font_write_be16 (font, 1);    cairo_pdf_ft_font_write_be16 (font, 1);    cairo_pdf_ft_font_write_be16 (font, 0);    cairo_pdf_ft_font_write_be32 (font, 12);    /* Output a format 6 encoding table. */    cairo_pdf_ft_font_write_be16 (font, 6);    cairo_pdf_ft_font_write_be16 (font, 10 + 2 * (font->base.num_glyphs - 1));    cairo_pdf_ft_font_write_be16 (font, 0);    cairo_pdf_ft_font_write_be16 (font, 1); /* First glyph */    cairo_pdf_ft_font_write_be16 (font, font->base.num_glyphs - 1);    for (i = 1; i < font->base.num_glyphs; i++)	cairo_pdf_ft_font_write_be16 (font, i);    return font->status;}static intcairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font,				       unsigned long tag){    cairo_status_t status;    unsigned char *buffer;    unsigned long size;    size = 0;    FT_Load_Sfnt_Table (font->face, tag, 0, NULL, &size);    status = cairo_pdf_ft_font_allocate_write_buffer (font, size, &buffer);    /* XXX: Need to check status here. */    FT_Load_Sfnt_Table (font->face, tag, 0, buffer, &size);    return 0;}typedef struct composite_glyph composite_glyph_t;struct composite_glyph {    unsigned short flags;    unsigned short index;    unsigned short args[7]; /* 1 to 7 arguments depending on value of flags */};typedef struct glyph_data glyph_data_t;struct glyph_data {    short             num_contours;    char              data[8];    composite_glyph_t glyph;};/* composite_glyph_t flags */#define ARG_1_AND_2_ARE_WORDS     0x0001#define WE_HAVE_A_SCALE           0x0008#define MORE_COMPONENTS           0x0020#define WE_HAVE_AN_X_AND_Y_SCALE  0x0040#define WE_HAVE_A_TWO_BY_TWO      0x0080static voidcairo_pdf_ft_font_remap_composite_glyph (cairo_pdf_ft_font_t *font,					 unsigned char *buffer){    glyph_data_t *glyph_data;    composite_glyph_t *composite_glyph;    int num_args;    int has_more_components;    unsigned short flags;    unsigned short index;    glyph_data = (glyph_data_t *) buffer;    if ((short)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 & MORE_COMPONENTS;        index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index));        composite_glyph->index = cpu_to_be16 (index);        num_args = 1;        if (flags & ARG_1_AND_2_ARE_WORDS)            num_args += 1;        if (flags & WE_HAVE_A_SCALE)            num_args += 1;        else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)            num_args += 2;        else if (flags & WE_HAVE_A_TWO_BY_TWO)            num_args += 3;        composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]);    } while (has_more_components);}static intcairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font,				    unsigned long tag){    cairo_status_t status;    unsigned long start_offset, index, size;    TT_Header *header;    unsigned long begin, end;    unsigned char *buffer;    int i;    union {	unsigned char *bytes;	unsigned short *short_offsets;	unsigned long *long_offsets;    } u;    header = FT_Get_Sfnt_Table (font->face, ft_sfnt_head);    if (header->Index_To_Loc_Format == 0)	size = sizeof (short) * (font->face->num_glyphs + 1);    else	size = sizeof (long) * (font->face->num_glyphs + 1);

⌨️ 快捷键说明

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