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

📄 cairo-ft-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
		fs_metrics.x_advance = 0;		fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor;	    }	 } else {	    fs_metrics.width  = DOUBLE_FROM_26_6 (metrics->width) * x_factor;	    fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;	    if (!vertical_layout) {		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;				fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;		fs_metrics.y_advance = 0 * y_factor;	    } else {		fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor;		fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor;				fs_metrics.x_advance = 0 * x_factor;		fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;	    }	 }	_cairo_scaled_glyph_set_metrics (scaled_glyph,					 &scaled_font->base,					 &fs_metrics);    }    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {	cairo_image_surface_t	*surface;	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {	    status = _render_glyph_outline (face, &scaled_font->ft_options.base,					    &surface);	} else {	    status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,					   &surface);	    if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape)		status = _transform_glyph_bitmap (&unscaled->current_shape,						  &surface);	}	if (status)	    goto FAIL;	_cairo_scaled_glyph_set_surface (scaled_glyph,					 &scaled_font->base,					 surface);    }    if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {	cairo_path_fixed_t *path;	/*	 * A kludge -- the above code will trash the outline,	 * so reload it. This will probably never occur though	 */	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {	    error = FT_Load_Glyph (face,				   _cairo_scaled_glyph_index(scaled_glyph),				   load_flags | FT_LOAD_NO_BITMAP);	    if (error) {		cairo_ft_scaled_font_unlock_face (abstract_font);		return CAIRO_STATUS_NO_MEMORY;	    }#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 (glyph->format == FT_GLYPH_FORMAT_OUTLINE)	    status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,					       &path);	else	    status = CAIRO_INT_STATUS_UNSUPPORTED;	if (status)	    goto FAIL;	_cairo_scaled_glyph_set_path (scaled_glyph,				      &scaled_font->base,				      path);    } FAIL:    cairo_ft_scaled_font_unlock_face (abstract_font);    return status;}static unsigned long_cairo_ft_ucs4_to_index (void	    *abstract_font,			 uint32_t    ucs4){    cairo_ft_scaled_font_t *scaled_font = abstract_font;    cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;    FT_Face face;    FT_UInt index;    face = _cairo_ft_unscaled_font_lock_face (unscaled);    if (!face)	return 0;    index = FT_Get_Char_Index (face, ucs4);    _cairo_ft_unscaled_font_unlock_face (unscaled);    return index;}static cairo_int_status_t_cairo_ft_show_glyphs (void		       *abstract_font,		       cairo_operator_t    	op,		       cairo_pattern_t     *pattern,		       cairo_surface_t     *surface,		       int                 	source_x,		       int                 	source_y,		       int			dest_x,		       int			dest_y,		       unsigned int		width,		       unsigned int		height,		       const cairo_glyph_t *glyphs,		       int                 	num_glyphs){    return CAIRO_INT_STATUS_UNSUPPORTED;}const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = {    CAIRO_FONT_TYPE_FT,    _cairo_ft_scaled_font_create_toy,    _cairo_ft_scaled_font_fini,    _cairo_ft_scaled_glyph_init,    NULL,			/* text_to_glyphs */    _cairo_ft_ucs4_to_index,    _cairo_ft_show_glyphs,};/* cairo_ft_font_face_t */static void_cairo_ft_font_face_destroy (void *abstract_face){    cairo_ft_font_face_t *font_face = abstract_face;    cairo_ft_font_face_t *tmp_face = NULL;    cairo_ft_font_face_t *last_face = NULL;    if (font_face == NULL)	return;    /* When destroying the face created by cairo_ft_font_face_create_for_ft_face,     * we have a special "zombie" state for the face when the unscaled font     * is still alive but there are no public references to the font face.     *     * We go from:     *     *   font_face ------> unscaled     *        <-....weak....../     *     * To:     *     *    font_face <------- unscaled     */    if (font_face->unscaled &&	font_face->unscaled->from_face &&	font_face->unscaled->base.ref_count > 1)    {	cairo_font_face_reference (&font_face->base);	_cairo_unscaled_font_destroy (&font_face->unscaled->base);	font_face->unscaled = NULL;	return;    }    if (font_face->unscaled) {	/* Remove face from linked list */	for (tmp_face = font_face->unscaled->faces;	     tmp_face;	     tmp_face = tmp_face->next)	{	    if (tmp_face == font_face) {		if (last_face)		    last_face->next = tmp_face->next;		else		    font_face->unscaled->faces = tmp_face->next;	    }	    last_face = tmp_face;	}	_cairo_unscaled_font_destroy (&font_face->unscaled->base);	font_face->unscaled = NULL;    }}static cairo_status_t_cairo_ft_font_face_scaled_font_create (void                     *abstract_face,					const cairo_matrix_t       *font_matrix,					const cairo_matrix_t       *ctm,					const cairo_font_options_t *options,					cairo_scaled_font_t       **scaled_font){    cairo_ft_font_face_t *font_face = abstract_face;    cairo_ft_options_t ft_options;    /* The handling of font options is different depending on how the     * font face was created. When the user creates a font face with     * cairo_ft_font_face_create_for_ft_face(), then the load flags     * passed in augment the load flags for the options.  But for     * cairo_ft_font_face_create_for_pattern(), the load flags are     * derived from a pattern where the user has called     * cairo_ft_font_options_substitute(), so *just* use those load     * flags and ignore the options.     */    ft_options = font_face->ft_options;    *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,						 &font_face->base,						 font_matrix, ctm,						 options, ft_options);    if (*scaled_font)	return CAIRO_STATUS_SUCCESS;    else	return CAIRO_STATUS_NO_MEMORY;}static const cairo_font_face_backend_t _cairo_ft_font_face_backend = {    CAIRO_FONT_TYPE_FT,    _cairo_ft_font_face_destroy,    _cairo_ft_font_face_scaled_font_create};static cairo_font_face_t *_cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,			    cairo_ft_options_t	      ft_options){    cairo_ft_font_face_t *font_face;    /* Looked for an existing matching font face */    for (font_face = unscaled->faces;	 font_face;	 font_face = font_face->next)    {	if (font_face->ft_options.load_flags == ft_options.load_flags &&	    font_face->ft_options.extra_flags == ft_options.extra_flags &&	    cairo_font_options_equal (&font_face->ft_options.base, &ft_options.base))	    return cairo_font_face_reference (&font_face->base);    }    /* No match found, create a new one */    font_face = malloc (sizeof (cairo_ft_font_face_t));    if (!font_face)	return NULL;    font_face->unscaled = unscaled;    _cairo_unscaled_font_reference (&unscaled->base);    font_face->ft_options = ft_options;    font_face->next = unscaled->faces;    unscaled->faces = font_face;    _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);    return &font_face->base;}/* implement the platform-specific interface *//** * cairo_ft_font_options_substitute: * @options: a #cairo_font_options_t object * @pattern: an existing #FcPattern * * Add options to a #FcPattern based on a #cairo_font_options_t font * options object. Options that are already in the pattern, are not overriden, * so you should call this function after calling FcConfigSubstitute() (the * user's settings should override options based on the surface type), but * before calling FcDefaultSubstitute(). **/voidcairo_ft_font_options_substitute (const cairo_font_options_t *options,				  FcPattern                  *pattern){    FcValue v;    if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)    {	if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)	{	    FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);	}    }    if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)    {	if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)	{	    int rgba;	    if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) {		switch (options->subpixel_order) {		case CAIRO_SUBPIXEL_ORDER_DEFAULT:		case CAIRO_SUBPIXEL_ORDER_RGB:		default:		    rgba = FC_RGBA_RGB;		    break;		case CAIRO_SUBPIXEL_ORDER_BGR:		    rgba = FC_RGBA_BGR;		    break;		case CAIRO_SUBPIXEL_ORDER_VRGB:		    rgba = FC_RGBA_VRGB;		    break;		case CAIRO_SUBPIXEL_ORDER_VBGR:		    rgba = FC_RGBA_VBGR;		    break;		}	    } else {		rgba = FC_RGBA_NONE;	    }	    FcPatternAddInteger (pattern, FC_RGBA, rgba);	}    }    if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)    {	if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)	{	    FcPatternAddBool (pattern, FC_HINTING, options->hint_style != CAIRO_HINT_STYLE_NONE);	}#ifdef FC_HINT_STYLE	if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)	{	    int hint_style;	    switch (options->hint_style) {	    case CAIRO_HINT_STYLE_SLIGHT:		hint_style = FC_HINT_SLIGHT;		break;	    case CAIRO_HINT_STYLE_MEDIUM:		hint_style = FC_HINT_MEDIUM;		break;	    case CAIRO_HINT_STYLE_FULL:	    default:		hint_style = FC_HINT_FULL;		break;	    }	    FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style);	}#endif    }}/** * cairo_ft_font_face_create_for_pattern: * @pattern: A fully resolved fontconfig *   pattern. A pattern can be resolved, by, among other things, calling *   FcConfigSubstitute(), FcDefaultSubstitute(), then *   FcFontMatch(). Cairo will call FcPatternReference() on this *   pattern, so you should not further modify the pattern, but you can *   release your reference to the pattern with FcPatternDestroy() if *   you no longer need to access it. * * Creates a new font face for the FreeType font backend based on a * fontconfig pattern. This font can then be used with * cairo_set_font_face() or cairo_scaled_font_create(). The * #cairo_scaled_font_t returned from cairo_scaled_font_create() is * also for the FreeType backend and can be used with functions such * as cairo_ft_font_lock_face(). * * Font rendering options are representated both here and when you * call cairo_scaled_font_create(). Font options that have a representation * in a #FcPattern must be passed in here; to modify #FcPattern * appropriately to reflect the options in a #cairo_font_options_t, call * cairo_ft_font_options_substitute(). * * Return value: a newly created #cairo_font_face_t. Free with *  cairo_font_face_destroy() when you are done using it. **/cairo_font_face_t *cairo_ft_font_face_create_for_pattern (FcPattern *pattern){    cairo_ft_unscaled_font_t *unscaled;    cairo_font_face_t *font_face;    unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);    if (unscaled == NULL) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_font_face_t *)&_cairo_font_face_nil;    }    font_face = _cairo_ft_font_face_create (unscaled,					    _get_pattern_ft_options (pattern));    _cairo_unscaled_font_destroy (&unscaled->base);    if (font_face)	return font_face;    else {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_font_face_t *)&_cairo_font_face_nil;    }}/** * cairo_ft_font_face_create_for_ft_face: * @face: A FreeType face object, already opened. This must *   be kept around until the face's ref_count drops to *   zero and it is freed. Since the face may be referenced *   internally to Cairo, the best way to determine when it *   is safe to free the face is to pass a *   #cairo_destroy_func_t to cairo_font_face_set_user_data() * @load_flags: flags to pass to FT_Load_Glyph when loading *   glyphs from the font. These flags are OR'ed together with *   the flags derived from the #cairo_font_options_t passed *   to cairo_scaled_font_create(), so only a few values such *   as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT *   are useful. You should not pass any of the flags affecting *   the load target, such as %FT_LOAD_TARGET_LIGHT. * * Creates a new font face for the FreeType font backend from a * pre-opened FreeType face. This font can then be used with * cairo_set_font_face() or cairo_scaled_font_create(). The * #cairo_scaled_font_t returned from cairo_scaled_font_create() is * also for the FreeType backend and can be used with functions such * as cairo_ft_font_lock_face(). * * Return value: a newly created #cairo_font_face_t. Free with *  cairo_font_face_destroy() when you are done using it. **/cairo_font_face_t *cairo_ft_font_face_create_for_ft_face (FT_Face         face,				       int             load_flags){    cairo_ft_unscaled_font_t *unscaled;    cairo_font_face_t *font_face;    cairo_ft_options_t ft_options;    unscaled = _cairo_ft_unscaled_font_create_from_face (face);    if (unscaled == NULL) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_font_face_t *)&_cairo_font_face_nil;    }    ft_options.load_flags = load_flags;    ft_options.extra_flags = 0;    _cairo_font_options_init_default (&ft_options.base);    font_face = _cairo_ft_font_face_create (unscaled, ft_options);    _cairo_unscaled_font_destroy (&unscaled->base);    if (font_face) {	return font_face;    } else {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_font_face_t *)&_cairo_font_face_nil;    }

⌨️ 快捷键说明

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