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

📄 cairo-scaled-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 3 页
字号:
					     glyphs[i].index,					     CAIRO_SCALED_GLYPH_INFO_SURFACE,					     &scaled_glyph);	if (status)	    goto CLEANUP_MASK;	glyph_surface = scaled_glyph->surface;	/* Create the mask using the format from the first glyph */	if (mask == NULL) {	    mask = cairo_image_surface_create (glyph_surface->format,					       width, height);	    if (mask->status) {		status = mask->status;		goto CLEANUP_MASK;	    }	    status = _cairo_surface_fill_rectangle (mask,						    CAIRO_OPERATOR_CLEAR,						    CAIRO_COLOR_TRANSPARENT,						    0, 0,						    width, height);	    if (status)		goto CLEANUP_MASK;	    if (glyph_surface->format == CAIRO_FORMAT_ARGB32)		pixman_image_set_component_alpha (((cairo_image_surface_t*) mask)->						  pixman_image, TRUE);	}	/* round glyph locations to the nearest pixel */	/* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */	x = (int) floor (glyphs[i].x +                         glyph_surface->base.device_transform.x0 +                         0.5);	y = (int) floor (glyphs[i].y +                         glyph_surface->base.device_transform.y0 +                         0.5);	_cairo_pattern_init_for_surface (&glyph_pattern, &glyph_surface->base);	status = _cairo_surface_composite (CAIRO_OPERATOR_ADD,					   &glyph_pattern.base,					   NULL,					   mask,					   0, 0,					   0, 0,					   x - dest_x,					   y - dest_y,					   glyph_surface->width,					   glyph_surface->height);	_cairo_pattern_fini (&glyph_pattern.base);	if (status)	    break;    }    if (mask != NULL) {	cairo_surface_pattern_t mask_pattern;	_cairo_pattern_init_for_surface (&mask_pattern, mask);	status = _cairo_surface_composite (op, pattern, &mask_pattern.base,					   surface,					   source_x, source_y,					   0,        0,					   dest_x,   dest_y,					   width,    height);	_cairo_pattern_fini (&mask_pattern.base);    }CLEANUP_MASK:    _cairo_cache_thaw (scaled_font->glyphs);    if (mask != NULL)	cairo_surface_destroy (mask);    return status;}typedef struct _cairo_scaled_glyph_path_closure {    cairo_point_t	    offset;    cairo_path_fixed_t	    *path;} cairo_scaled_glyph_path_closure_t;static cairo_status_t_scaled_glyph_path_move_to (void *abstract_closure, cairo_point_t *point){    cairo_scaled_glyph_path_closure_t	*closure = abstract_closure;    return _cairo_path_fixed_move_to (closure->path,				      point->x + closure->offset.x,				      point->y + closure->offset.y);}static cairo_status_t_scaled_glyph_path_line_to (void *abstract_closure, cairo_point_t *point){    cairo_scaled_glyph_path_closure_t	*closure = abstract_closure;    return _cairo_path_fixed_line_to (closure->path,				      point->x + closure->offset.x,				      point->y + closure->offset.y);}static cairo_status_t_scaled_glyph_path_curve_to (void *abstract_closure,			     cairo_point_t *p0,			     cairo_point_t *p1,			     cairo_point_t *p2){    cairo_scaled_glyph_path_closure_t	*closure = abstract_closure;    return _cairo_path_fixed_curve_to (closure->path,				       p0->x + closure->offset.x,				       p0->y + closure->offset.y,				       p1->x + closure->offset.x,				       p1->y + closure->offset.y,				       p2->x + closure->offset.x,				       p2->y + closure->offset.y);}static cairo_status_t_scaled_glyph_path_close_path (void *abstract_closure){    cairo_scaled_glyph_path_closure_t	*closure = abstract_closure;    return _cairo_path_fixed_close_path (closure->path);}cairo_status_t_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,			       const cairo_glyph_t *glyphs,			       int		    num_glyphs,			       cairo_path_fixed_t  *path){    cairo_status_t status;    int	i;    cairo_scaled_glyph_path_closure_t closure;    if (scaled_font->status)	return scaled_font->status;    closure.path = path;    for (i = 0; i < num_glyphs; i++) {	cairo_scaled_glyph_t *scaled_glyph;	status = _cairo_scaled_glyph_lookup (scaled_font,					     glyphs[i].index,					     CAIRO_SCALED_GLYPH_INFO_PATH,					     &scaled_glyph);	if (status)	    return status;	closure.offset.x = _cairo_fixed_from_double (glyphs[i].x);	closure.offset.y = _cairo_fixed_from_double (glyphs[i].y);	status = _cairo_path_fixed_interpret (scaled_glyph->path,					      CAIRO_DIRECTION_FORWARD,					      _scaled_glyph_path_move_to,					      _scaled_glyph_path_line_to,					      _scaled_glyph_path_curve_to,					      _scaled_glyph_path_close_path,					      &closure);    }    return CAIRO_STATUS_SUCCESS;}/** * cairo_scaled_glyph_set_metrics: * @scaled_glyph: a #cairo_scaled_glyph_t * @scaled_font: a #cairo_scaled_font_t * @fs_metrics: a #cairo_text_extents_t in font space * * _cairo_scaled_glyph_set_metrics() stores user space metrics * for the specified glyph given font space metrics. It is * called by the font backend when initializing a glyph with * CAIRO_SCALED_GLYPH_INFO_METRICS. **/void_cairo_scaled_glyph_set_metrics (cairo_scaled_glyph_t *scaled_glyph,				 cairo_scaled_font_t *scaled_font,				 cairo_text_extents_t *fs_metrics){    cairo_bool_t first = TRUE;    double hm, wm;    double min_user_x = 0.0, max_user_x = 0.0, min_user_y = 0.0, max_user_y = 0.0;    double min_device_x = 0.0, max_device_x = 0.0, min_device_y = 0.0, max_device_y = 0.0;    for (hm = 0.0; hm <= 1.0; hm += 1.0)	for (wm = 0.0; wm <= 1.0; wm += 1.0) {	    double x, y;	    /* Transform this corner to user space */	    x = fs_metrics->x_bearing + fs_metrics->width * wm;	    y = fs_metrics->y_bearing + fs_metrics->height * hm;	    cairo_matrix_transform_point (&scaled_font->font_matrix,					  &x, &y);	    if (first) {		min_user_x = max_user_x = x;		min_user_y = max_user_y = y;	    } else {		if (x < min_user_x) min_user_x = x;		if (x > max_user_x) max_user_x = x;		if (y < min_user_y) min_user_y = y;		if (y > max_user_y) max_user_y = y;	    }	    /* Transform this corner to device space from glyph origin */	    x = fs_metrics->x_bearing + fs_metrics->width * wm;	    y = fs_metrics->y_bearing + fs_metrics->height * hm;	    cairo_matrix_transform_distance (&scaled_font->scale,					     &x, &y);	    if (first) {		min_device_x = max_device_x = x;		min_device_y = max_device_y = y;	    } else {		if (x < min_device_x) min_device_x = x;		if (x > max_device_x) max_device_x = x;		if (y < min_device_y) min_device_y = y;		if (y > max_device_y) max_device_y = y;	    }	    first = FALSE;	}    scaled_glyph->metrics.x_bearing = min_user_x;    scaled_glyph->metrics.y_bearing = min_user_y;    scaled_glyph->metrics.width = max_user_x - min_user_x;    scaled_glyph->metrics.height = max_user_y - min_user_y;    scaled_glyph->metrics.x_advance = fs_metrics->x_advance;    scaled_glyph->metrics.y_advance = fs_metrics->y_advance;    cairo_matrix_transform_point (&scaled_font->font_matrix,				  &scaled_glyph->metrics.x_advance,				  &scaled_glyph->metrics.y_advance);    scaled_glyph->bbox.p1.x = _cairo_fixed_from_double (min_device_x);    scaled_glyph->bbox.p1.y = _cairo_fixed_from_double (min_device_y);    scaled_glyph->bbox.p2.x = _cairo_fixed_from_double (max_device_x);    scaled_glyph->bbox.p2.y = _cairo_fixed_from_double (max_device_y);}void_cairo_scaled_glyph_set_surface (cairo_scaled_glyph_t *scaled_glyph,				 cairo_scaled_font_t *scaled_font,				 cairo_image_surface_t *surface){    if (scaled_glyph->surface != NULL)	cairo_surface_destroy (&scaled_glyph->surface->base);    scaled_glyph->surface = surface;}void_cairo_scaled_glyph_set_path (cairo_scaled_glyph_t *scaled_glyph,			      cairo_scaled_font_t *scaled_font,			      cairo_path_fixed_t *path){    if (scaled_glyph->path != NULL)	_cairo_path_fixed_destroy (scaled_glyph->path);    scaled_glyph->path = path;}/** * _cairo_scaled_glyph_lookup: * @scaled_font: a #cairo_scaled_font_t * @index: the glyph to create * @info: a #cairo_scaled_glyph_info_t marking which portions of * the glyph should be filled in. * @scaled_glyph_ret: a #cairo_scaled_glyph_t * where the glyph * is returned. * * Returns a glyph with the requested portions filled in. Glyph * lookup is cached and glyph will be automatically freed along * with the scaled_font so no explicit free is required. * @info can be one or more of: *  %CAIRO_SCALED_GLYPH_INFO_METRICS - glyph metrics and bounding box *  %CAIRO_SCALED_GLYPH_INFO_SURFACE - surface holding glyph image *  %CAIRO_SCALED_GLYPH_INFO_PATH - path holding glyph outline in device space * * If the desired info is not available, (for example, when trying to * get INFO_PATH with a bitmapped font), this function will return * CAIRO_INT_STATUS_UNSUPPORTED. **/cairo_int_status_t_cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,			    unsigned long index,			    cairo_scaled_glyph_info_t info,			    cairo_scaled_glyph_t **scaled_glyph_ret){    cairo_status_t		status = CAIRO_STATUS_SUCCESS;    cairo_cache_entry_t		key;    cairo_scaled_glyph_t	*scaled_glyph;    cairo_scaled_glyph_info_t	need_info;    if (scaled_font->status)	return scaled_font->status;    CAIRO_MUTEX_LOCK (cairo_scaled_font_map_mutex);    key.hash = index;    /*     * Check cache for glyph     */    info |= CAIRO_SCALED_GLYPH_INFO_METRICS;    if (!_cairo_cache_lookup (scaled_font->glyphs, &key,			      (cairo_cache_entry_t **) &scaled_glyph))    {	/*	 * On miss, create glyph and insert into cache	 */	scaled_glyph = malloc (sizeof (cairo_scaled_glyph_t));	if (scaled_glyph == NULL) {	    status = CAIRO_STATUS_NO_MEMORY;	    goto CLEANUP;	}	_cairo_scaled_glyph_set_index(scaled_glyph, index);	scaled_glyph->cache_entry.size = 1;	/* XXX */	scaled_glyph->scaled_font = scaled_font;	scaled_glyph->surface = NULL;	scaled_glyph->path = NULL;	scaled_glyph->surface_private = NULL;	/* ask backend to initialize metrics and shape fields */	status = (*scaled_font->backend->		  scaled_glyph_init) (scaled_font, scaled_glyph, info);	if (status) {	    _cairo_scaled_glyph_destroy (scaled_glyph);	    goto CLEANUP;	}	/* on success, the cache takes ownership of the scaled_glyph */	status = _cairo_cache_insert (scaled_font->glyphs,				      &scaled_glyph->cache_entry);	if (status) {	    _cairo_scaled_glyph_destroy (scaled_glyph);	    goto CLEANUP;	}    }    /*     * Check and see if the glyph, as provided,     * already has the requested data and ammend it if not     */    need_info = 0;    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0 &&	scaled_glyph->surface == NULL)	need_info |= CAIRO_SCALED_GLYPH_INFO_SURFACE;    if (((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 &&	 scaled_glyph->path == NULL))	need_info |= CAIRO_SCALED_GLYPH_INFO_PATH;    if (need_info) {	status = (*scaled_font->backend->		  scaled_glyph_init) (scaled_font, scaled_glyph, need_info);	if (status)	    goto CLEANUP;    }  CLEANUP:    if (status) {	/* It's not an error for the backend to not support the info we want. */	if (status != CAIRO_INT_STATUS_UNSUPPORTED)	    _cairo_scaled_font_set_error (scaled_font, status);	*scaled_glyph_ret = NULL;    } else {	*scaled_glyph_ret = scaled_glyph;    }    CAIRO_MUTEX_UNLOCK (cairo_scaled_font_map_mutex);    return status;}/** * cairo_scaled_font_get_font_face: * @scaled_font: a #cairo_scaled_font_t * * Return value: The #cairo_font_face_t with which @scaled_font was * created. * * Since: 1.2 **/cairo_font_face_t *cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font){    if (scaled_font->status)	return (cairo_font_face_t*) &_cairo_font_face_nil;    return scaled_font->font_face;}/** * cairo_scaled_font_get_font_matrix: * @scaled_font: a #cairo_scaled_font_t * @font_matrix: return value for the matrix * * Stores the font matrix with which @scaled_font was created into * @matrix. * * Since: 1.2 **/voidcairo_scaled_font_get_font_matrix (cairo_scaled_font_t	*scaled_font,				   cairo_matrix_t	*font_matrix){    if (scaled_font->status) {	cairo_matrix_init_identity (font_matrix);	return;    }    *font_matrix = scaled_font->font_matrix;}/** * cairo_scaled_font_get_ctm: * @scaled_font: a #cairo_scaled_font_t * @ctm: return value for the CTM * * Stores the CTM with which @scaled_font was created into @ctm. * * Since: 1.2 **/voidcairo_scaled_font_get_ctm (cairo_scaled_font_t	*scaled_font,			   cairo_matrix_t	*ctm){    if (scaled_font->status) {	cairo_matrix_init_identity (ctm);	return;    }    *ctm = scaled_font->ctm;}/** * cairo_scaled_font_get_font_options: * @scaled_font: a #cairo_scaled_font_t * @options: return value for the font options * * Stores the font options with which @scaled_font was created into * @ctm. * * Since: 1.2 **/voidcairo_scaled_font_get_font_options (cairo_scaled_font_t		*scaled_font,				    cairo_font_options_t	*options){    if (scaled_font->status) {	_cairo_font_options_init_default (options);	return;    }    _cairo_font_options_init_copy (options, &scaled_font->options);}

⌨️ 快捷键说明

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