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

📄 cairo-ft-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
static cairo_scaled_font_t *_cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t	 *unscaled,			      cairo_font_face_t		 *font_face,			      const cairo_matrix_t	 *font_matrix,			      const cairo_matrix_t	 *ctm,			      const cairo_font_options_t *options,			      cairo_ft_options_t	  ft_options){    cairo_ft_scaled_font_t *scaled_font = NULL;    FT_Face face;    FT_Size_Metrics *metrics;    cairo_font_extents_t fs_metrics;    face = _cairo_ft_unscaled_font_lock_face (unscaled);    if (!face)	return NULL;    scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));    if (scaled_font == NULL) {	_cairo_ft_unscaled_font_unlock_face (unscaled);	return NULL;    }    _cairo_unscaled_font_reference (&unscaled->base);    scaled_font->unscaled = unscaled;    if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)	ft_options.extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;    _cairo_font_options_init_copy (&scaled_font->ft_options.base, options);    _cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);    _cairo_scaled_font_init (&scaled_font->base,			     font_face,			     font_matrix, ctm, options,			     &cairo_ft_scaled_font_backend);    _cairo_ft_unscaled_font_set_scale (unscaled,				       &scaled_font->base.scale);    metrics = &face->size->metrics;    /*     * Get to unscaled metrics so that the upper level can get back to     * user space     */    if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) {	double x_factor, y_factor;	if (unscaled->x_scale == 0)	    x_factor = 0;	else	    x_factor = 1 / unscaled->x_scale;	if (unscaled->y_scale == 0)	    y_factor = 0;	else	    y_factor = 1 / unscaled->y_scale;	fs_metrics.ascent =        DOUBLE_FROM_26_6(metrics->ascender) * y_factor;	fs_metrics.descent =       DOUBLE_FROM_26_6(- metrics->descender) * y_factor;	fs_metrics.height =        DOUBLE_FROM_26_6(metrics->height) * y_factor;	if (!(scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)) {	    fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor;	    fs_metrics.max_y_advance = 0;	} else {	    fs_metrics.max_x_advance = 0;	    fs_metrics.max_y_advance = DOUBLE_FROM_26_6(metrics->max_advance) * y_factor;	}    } else {	double scale = face->units_per_EM;	fs_metrics.ascent =        face->ascender / scale;	fs_metrics.descent =       - face->descender / scale;	fs_metrics.height =        face->height / scale;	if (!(scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)) {	    fs_metrics.max_x_advance = face->max_advance_width / scale;	    fs_metrics.max_y_advance = 0;	} else {	    fs_metrics.max_x_advance = 0;	    fs_metrics.max_y_advance = face->max_advance_height / scale;	}    }    _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics);    return &scaled_font->base;}cairo_bool_t_cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font){    return scaled_font->backend == &cairo_ft_scaled_font_backend;}static cairo_status_t_cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t	      *toy_face,				  const cairo_matrix_t	      *font_matrix,				  const cairo_matrix_t	      *ctm,				  const cairo_font_options_t  *font_options,				  cairo_scaled_font_t	     **font){    FcPattern *pattern, *resolved;    cairo_ft_unscaled_font_t *unscaled;    cairo_scaled_font_t *new_font = NULL;    FcResult result;    int fcslant;    int fcweight;    cairo_matrix_t scale;    cairo_ft_font_transform_t sf;    cairo_ft_options_t ft_options;    unsigned char *family = (unsigned char*) toy_face->family;    pattern = FcPatternCreate ();    if (!pattern)	return CAIRO_STATUS_NO_MEMORY;    switch (toy_face->weight)    {    case CAIRO_FONT_WEIGHT_BOLD:        fcweight = FC_WEIGHT_BOLD;        break;    case CAIRO_FONT_WEIGHT_NORMAL:    default:        fcweight = FC_WEIGHT_MEDIUM;        break;    }    switch (toy_face->slant)    {    case CAIRO_FONT_SLANT_ITALIC:        fcslant = FC_SLANT_ITALIC;        break;    case CAIRO_FONT_SLANT_OBLIQUE:	fcslant = FC_SLANT_OBLIQUE;        break;    case CAIRO_FONT_SLANT_NORMAL:    default:        fcslant = FC_SLANT_ROMAN;        break;    }    if (!FcPatternAddString (pattern, FC_FAMILY, family))	goto FREE_PATTERN;    if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant))	goto FREE_PATTERN;    if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight))	goto FREE_PATTERN;    cairo_matrix_multiply (&scale, font_matrix, ctm);    _compute_transform (&sf, &scale);    FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale);    FcConfigSubstitute (NULL, pattern, FcMatchPattern);    cairo_ft_font_options_substitute (font_options, pattern);    FcDefaultSubstitute (pattern);    resolved = FcFontMatch (NULL, pattern, &result);    if (!resolved)	goto FREE_PATTERN;    unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);    if (!unscaled)	goto FREE_RESOLVED;    ft_options = _get_pattern_ft_options (resolved);    new_font = _cairo_ft_scaled_font_create (unscaled,					     &toy_face->base,					     font_matrix, ctm,					     font_options, ft_options);    _cairo_unscaled_font_destroy (&unscaled->base); FREE_RESOLVED:    FcPatternDestroy (resolved); FREE_PATTERN:    FcPatternDestroy (pattern);    if (new_font) {	*font = new_font;	return CAIRO_STATUS_SUCCESS;    } else {	return CAIRO_STATUS_NO_MEMORY;    }}static void_cairo_ft_scaled_font_fini (void *abstract_font){    cairo_ft_scaled_font_t *scaled_font = abstract_font;    if (scaled_font == NULL)        return;    _cairo_unscaled_font_destroy (&scaled_font->unscaled->base);}static int_move_to (FT_Vector *to, void *closure){    cairo_path_fixed_t *path = closure;    cairo_fixed_t x, y;    x = _cairo_fixed_from_26_6 (to->x);    y = _cairo_fixed_from_26_6 (to->y);    _cairo_path_fixed_close_path (path);    _cairo_path_fixed_move_to (path, x, y);    return 0;}static int_line_to (FT_Vector *to, void *closure){    cairo_path_fixed_t *path = closure;    cairo_fixed_t x, y;    x = _cairo_fixed_from_26_6 (to->x);    y = _cairo_fixed_from_26_6 (to->y);    _cairo_path_fixed_line_to (path, x, y);    return 0;}static int_conic_to (FT_Vector *control, FT_Vector *to, void *closure){    cairo_path_fixed_t *path = closure;    cairo_fixed_t x0, y0;    cairo_fixed_t x1, y1;    cairo_fixed_t x2, y2;    cairo_fixed_t x3, y3;    cairo_point_t conic;    _cairo_path_fixed_get_current_point (path, &x0, &y0);    conic.x = _cairo_fixed_from_26_6 (control->x);    conic.y = _cairo_fixed_from_26_6 (control->y);    x3 = _cairo_fixed_from_26_6 (to->x);    y3 = _cairo_fixed_from_26_6 (to->y);    x1 = x0 + 2.0/3.0 * (conic.x - x0);    y1 = y0 + 2.0/3.0 * (conic.y - y0);    x2 = x3 + 2.0/3.0 * (conic.x - x3);    y2 = y3 + 2.0/3.0 * (conic.y - y3);    _cairo_path_fixed_curve_to (path,				x1, y1,				x2, y2,				x3, y3);    return 0;}static int_cubic_to (FT_Vector *control1, FT_Vector *control2,	   FT_Vector *to, void *closure){    cairo_path_fixed_t *path = closure;    cairo_fixed_t x0, y0;    cairo_fixed_t x1, y1;    cairo_fixed_t x2, y2;    x0 = _cairo_fixed_from_26_6 (control1->x);    y0 = _cairo_fixed_from_26_6 (control1->y);    x1 = _cairo_fixed_from_26_6 (control2->x);    y1 = _cairo_fixed_from_26_6 (control2->y);    x2 = _cairo_fixed_from_26_6 (to->x);    y2 = _cairo_fixed_from_26_6 (to->y);    _cairo_path_fixed_curve_to (path,				x0, y0,				x1, y1,				x2, y2);    return 0;}static cairo_status_t_decompose_glyph_outline (FT_Face		  face,			  cairo_font_options_t	 *options,			  cairo_path_fixed_t	**pathp){    static const FT_Outline_Funcs outline_funcs = {	(FT_Outline_MoveToFunc)_move_to,	(FT_Outline_LineToFunc)_line_to,	(FT_Outline_ConicToFunc)_conic_to,	(FT_Outline_CubicToFunc)_cubic_to,	0, /* shift */	0, /* delta */    };    static const FT_Matrix invert_y = {	DOUBLE_TO_16_16 (1.0), 0,	0, DOUBLE_TO_16_16 (-1.0),    };    FT_GlyphSlot glyph;    cairo_path_fixed_t *path;    path = _cairo_path_fixed_create ();    if (!path)	return CAIRO_STATUS_NO_MEMORY;    glyph = face->glyph;    /* Font glyphs have an inverted Y axis compared to cairo. */    FT_Outline_Transform (&glyph->outline, &invert_y);    FT_Outline_Decompose (&glyph->outline, &outline_funcs, path);    _cairo_path_fixed_close_path (path);    *pathp = path;    return CAIRO_STATUS_SUCCESS;}/* * Translate glyph to match its metrics. */static void_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (FT_GlyphSlot glyph){    FT_Pos x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX;    FT_Pos y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY;    if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)	FT_Outline_Translate(&glyph->outline, x, y);    else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {	glyph->bitmap_left += x / 64;	glyph->bitmap_top  += y / 64;    }}static cairo_int_status_t_cairo_ft_scaled_glyph_init (void			*abstract_font,			     cairo_scaled_glyph_t	*scaled_glyph,			     cairo_scaled_glyph_info_t	 info){    cairo_text_extents_t    fs_metrics;    cairo_ft_scaled_font_t *scaled_font = abstract_font;    cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;    FT_GlyphSlot glyph;    FT_Face face;    FT_Error error;    int load_flags = scaled_font->ft_options.load_flags;    FT_Glyph_Metrics *metrics;    double x_factor, y_factor;    cairo_bool_t vertical_layout = FALSE;    cairo_status_t status = CAIRO_STATUS_SUCCESS;    face = cairo_ft_scaled_font_lock_face (abstract_font);    if (!face)	return CAIRO_STATUS_NO_MEMORY;    /* Ignore global advance unconditionally */    load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;    if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&	(info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0)	load_flags |= FT_LOAD_NO_BITMAP;    /*     * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as     * suggested by freetype people.     */    if (load_flags & FT_LOAD_VERTICAL_LAYOUT) {	load_flags &= ~FT_LOAD_VERTICAL_LAYOUT;	vertical_layout = TRUE;    }    error = FT_Load_Glyph (scaled_font->unscaled->face,			   _cairo_scaled_glyph_index(scaled_glyph),			   load_flags);    if (error) {	status = CAIRO_STATUS_NO_MEMORY;	goto FAIL;    }    glyph = face->glyph;#if HAVE_FT_GLYPHSLOT_EMBOLDEN    /*     * embolden glyphs if requested     */    if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)	FT_GlyphSlot_Embolden (glyph);#endif    if (vertical_layout)	_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (glyph);    if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {	/*	 * Compute font-space metrics	 */	metrics = &glyph->metrics;	if (unscaled->x_scale == 0)	    x_factor = 0;	else	    x_factor = 1 / unscaled->x_scale;	if (unscaled->y_scale == 0)	    y_factor = 0;	else	    y_factor = 1 / unscaled->y_scale;	/*	 * Note: the font's coordinate system is upside down from ours, so the	 * Y coordinates of the bearing and advance need to be negated.	 *	 * Scale metrics back to glyph space from the scaled glyph space returned	 * by FreeType	 *	 * If we want hinted metrics but aren't asking for hinted glyphs from	 * FreeType, then we need to do the metric hinting ourselves.	 */	if ((scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) &&	    (load_flags & FT_LOAD_NO_HINTING))	{	    FT_Pos x1, x2;	    FT_Pos y1, y2;	    FT_Pos advance;	    	    if (!vertical_layout) {		x1 = (metrics->horiBearingX) & -64;		x2 = (metrics->horiBearingX + metrics->width + 63) & -64;		y1 = (-metrics->horiBearingY) & -64;		y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;				advance = ((metrics->horiAdvance + 32) & -64);				fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;				fs_metrics.width  = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;		fs_metrics.height  = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;		fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;		fs_metrics.y_advance = 0;	    } else {		x1 = (metrics->vertBearingX) & -64;		x2 = (metrics->vertBearingX + metrics->width + 63) & -64;		y1 = (metrics->vertBearingY) & -64;		y2 = (metrics->vertBearingY + metrics->height + 63) & -64;				advance = ((metrics->vertAdvance + 32) & -64);				fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;				fs_metrics.width  = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;		fs_metrics.height  = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;

⌨️ 快捷键说明

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