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

📄 cairo-scaled-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 3 页
字号:
				  (cairo_hash_entry_t**) &scaled_font))    {	_cairo_scaled_font_map_unlock ();	return cairo_scaled_font_reference (scaled_font);    }    /* Otherwise create it and insert it into the hash table. */    status = font_face->backend->scaled_font_create (font_face, font_matrix,						     ctm, options, &scaled_font);    if (status)	goto UNWIND_FONT_MAP_LOCK;    status = _cairo_hash_table_insert (font_map->hash_table,				       &scaled_font->hash_entry);    if (status)	goto UNWIND_SCALED_FONT_CREATE;    _cairo_scaled_font_map_unlock ();    return scaled_font;UNWIND_SCALED_FONT_CREATE:    /* We can't call _cairo_scaled_font_destroy here since it expects     * that the font has already been successfully inserted into the     * hash table. */    _cairo_scaled_font_fini (scaled_font);    free (scaled_font);UNWIND_FONT_MAP_LOCK:    _cairo_scaled_font_map_unlock ();UNWIND:    return NULL;}/** * cairo_scaled_font_reference: * @scaled_font: a #cairo_scaled_font_t, (may be NULL in which case * this function does nothing) * * Increases the reference count on @scaled_font by one. This prevents * @scaled_font from being destroyed until a matching call to * cairo_scaled_font_destroy() is made. * * Returns: the referenced #cairo_scaled_font_t **/cairo_scaled_font_t *cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font){    cairo_scaled_font_map_t *font_map;    if (scaled_font == NULL)	return NULL;    if (scaled_font->ref_count == (unsigned int)-1)	return scaled_font;    /* We would normally assert (scaled_font->ref_count > 0) here, but     * we are using ref_count == 0 as a legitimate case for the     * holdovers array. See below. */    /* cairo_scaled_font_t objects are cached and shared between     * threads. This works because these objects are immutable. Except     * that the reference count is mutable, so we have to do locking     * around any modification of the reference count. */    font_map = _cairo_scaled_font_map_lock ();    {	/* If the original reference count is 0, then this font must have	 * been found in font_map->holdovers, (which means this caching is	 * actually working). So now we remove it from the holdovers	 * array. */	if (scaled_font->ref_count == 0) {	    int i;	    for (i = 0; i < font_map->num_holdovers; i++)		if (font_map->holdovers[i] == scaled_font)		    break;	    assert (i < font_map->num_holdovers);	    font_map->num_holdovers--;	    memmove (&font_map->holdovers[i],		     &font_map->holdovers[i+1],		     (font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*));	}	scaled_font->ref_count++;    }    _cairo_scaled_font_map_unlock ();    return scaled_font;}/** * cairo_scaled_font_destroy: * @scaled_font: a #cairo_scaled_font_t * * Decreases the reference count on @font by one. If the result * is zero, then @font and all associated resources are freed. * See cairo_scaled_font_reference(). **/voidcairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font){    cairo_scaled_font_map_t *font_map;    if (scaled_font == NULL)	return;    if (scaled_font->ref_count == (unsigned int)-1)	return;    /* cairo_scaled_font_t objects are cached and shared between     * threads. This works because these objects are immutable. Except     * that the reference count is mutable, so we have to do locking     * around any modification of the reference count. */    font_map = _cairo_scaled_font_map_lock ();    {	assert (font_map != NULL);	assert (scaled_font->ref_count > 0);	if (--(scaled_font->ref_count) == 0)	{	    /* Rather than immediately destroying this object, we put it into	     * the font_map->holdovers array in case it will get used again	     * soon. To make room for it, we do actually destroy the	     * least-recently-used holdover.	     */	    if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS) {		cairo_scaled_font_t *lru;		lru = font_map->holdovers[0];		assert (lru->ref_count == 0);		_cairo_hash_table_remove (font_map->hash_table, &lru->hash_entry);		_cairo_scaled_font_fini (lru);		free (lru);		font_map->num_holdovers--;		memmove (&font_map->holdovers[0],			 &font_map->holdovers[1],			 font_map->num_holdovers * sizeof (cairo_scaled_font_t*));	    }	    font_map->holdovers[font_map->num_holdovers] = scaled_font;	    font_map->num_holdovers++;	}    }    _cairo_scaled_font_map_unlock ();}/* Public font API follows. *//** * cairo_scaled_font_extents: * @scaled_font: a #cairo_scaled_font_t * @extents: a #cairo_font_extents_t which to store the retrieved extents. * * Gets the metrics for a #cairo_scaled_font_t. **/voidcairo_scaled_font_extents (cairo_scaled_font_t  *scaled_font,			   cairo_font_extents_t *extents){    *extents = scaled_font->extents;}/** * cairo_scaled_font_text_extents: * @scaled_font: a #cairo_scaled_font_t * @utf8: a string of text, encoded in UTF-8 * @extents: a #cairo_text_extents_t which to store the retrieved extents. * * Gets the extents for a string of text. The extents describe a * user-space rectangle that encloses the "inked" portion of the text * drawn at the origin (0,0) (as it would be drawn by cairo_show_text() * if the cairo graphics state were set to the same font_face, * font_matrix, ctm, and font_options as @scaled_font).  Additionally, * the x_advance and y_advance values indicate the amount by which the * current point would be advanced by cairo_show_text(). * * Note that whitespace characters do not directly contribute to the * size of the rectangle (extents.width and extents.height). They do * contribute indirectly by changing the position of non-whitespace * characters. In particular, trailing whitespace characters are * likely to not affect the size of the rectangle, though they will * affect the x_advance and y_advance values. * * Since: 1.2 **/voidcairo_scaled_font_text_extents (cairo_scaled_font_t   *scaled_font,				const char            *utf8,				cairo_text_extents_t  *extents){    cairo_status_t status = CAIRO_STATUS_SUCCESS;    cairo_glyph_t *glyphs;    int num_glyphs;    status = _cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., utf8, &glyphs, &num_glyphs);    if (status) {        _cairo_scaled_font_set_error (scaled_font, status);        return;    }    cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents);    free (glyphs);}/** * cairo_scaled_font_glyph_extents: * @scaled_font: a #cairo_scaled_font_t * @glyphs: an array of glyph IDs with X and Y offsets. * @num_glyphs: the number of glyphs in the @glyphs array * @extents: a #cairo_text_extents_t which to store the retrieved extents. * * Gets the extents for an array of glyphs. The extents describe a * user-space rectangle that encloses the "inked" portion of the * glyphs, (as they would be drawn by cairo_show_glyphs() if the cairo * graphics state were set to the same font_face, font_matrix, ctm, * and font_options as @scaled_font).  Additionally, the x_advance and * y_advance values indicate the amount by which the current point * would be advanced by cairo_show_glyphs. * * Note that whitespace glyphs do not contribute to the size of the * rectangle (extents.width and extents.height). **/voidcairo_scaled_font_glyph_extents (cairo_scaled_font_t   *scaled_font,				 cairo_glyph_t         *glyphs,				 int                    num_glyphs,				 cairo_text_extents_t  *extents){    cairo_status_t status = CAIRO_STATUS_SUCCESS;    int i;    double min_x = 0.0, min_y = 0.0, max_x = 0.0, max_y = 0.0;    double x_pos = 0.0, y_pos = 0.0;    if (scaled_font->status)	return;    if (!num_glyphs) {	extents->x_bearing = 0.0;	extents->y_bearing = 0.0;	extents->width = 0.0;	extents->height = 0.0;	extents->x_advance = 0.0;	extents->y_advance = 0.0;	return;    }    for (i = 0; i < num_glyphs; i++) {	cairo_scaled_glyph_t	*scaled_glyph;	double			left, top, right, bottom;	status = _cairo_scaled_glyph_lookup (scaled_font,					     glyphs[i].index,					     CAIRO_SCALED_GLYPH_INFO_METRICS,					     &scaled_glyph);	if (status) {	    _cairo_scaled_font_set_error (scaled_font, status);	    return;	}	left = scaled_glyph->metrics.x_bearing + glyphs[i].x;	right = left + scaled_glyph->metrics.width;	top = scaled_glyph->metrics.y_bearing + glyphs[i].y;	bottom = top + scaled_glyph->metrics.height;	if (i == 0) {	    min_x = left;	    max_x = right;	    min_y = top;	    max_y = bottom;	} else {	    if (left < min_x) min_x = left;	    if (right > max_x) max_x = right;	    if (top < min_y) min_y = top;	    if (bottom > max_y) max_y = bottom;	}	x_pos = glyphs[i].x + scaled_glyph->metrics.x_advance;	y_pos = glyphs[i].y + scaled_glyph->metrics.y_advance;    }    extents->x_bearing = min_x - glyphs[0].x;    extents->y_bearing = min_y - glyphs[0].y;    extents->width = max_x - min_x;    extents->height = max_y - min_y;    extents->x_advance = x_pos - glyphs[0].x;    extents->y_advance = y_pos - glyphs[0].y;}cairo_status_t_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,				   double		x,				   double		y,				   const char          *utf8,				   cairo_glyph_t      **glyphs,				   int 		       *num_glyphs){    size_t i;    uint32_t *ucs4 = NULL;    cairo_status_t status = CAIRO_STATUS_SUCCESS;    cairo_scaled_glyph_t *scaled_glyph;    if (scaled_font->backend->text_to_glyphs) {	status = scaled_font->backend->text_to_glyphs (scaled_font,						       x, y, utf8,						       glyphs, num_glyphs);        if (status != CAIRO_INT_STATUS_UNSUPPORTED)            return status;    }    status = _cairo_utf8_to_ucs4 ((unsigned char*)utf8, -1, &ucs4, num_glyphs);    if (status)	return status;    *glyphs = (cairo_glyph_t *) malloc ((*num_glyphs) * (sizeof (cairo_glyph_t)));    if (*glyphs == NULL) {	status = CAIRO_STATUS_NO_MEMORY;	goto FAIL;    }    for (i = 0; i < *num_glyphs; i++) {        (*glyphs)[i].index = (*scaled_font->backend->			      ucs4_to_index) (scaled_font, ucs4[i]);	(*glyphs)[i].x = x;	(*glyphs)[i].y = y;	status = _cairo_scaled_glyph_lookup (scaled_font,					     (*glyphs)[i].index,					     CAIRO_SCALED_GLYPH_INFO_METRICS,					     &scaled_glyph);	if (status) {	    free (*glyphs);	    *glyphs = NULL;	    goto FAIL;	}        x += scaled_glyph->metrics.x_advance;        y += scaled_glyph->metrics.y_advance;    } FAIL:    free (ucs4);    return status;}/* * Compute a device-space bounding box for the glyphs. */cairo_status_t_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t	 *scaled_font,					 const cairo_glyph_t	 *glyphs,					 int                      num_glyphs,					 cairo_rectangle_int16_t *extents){    cairo_status_t status = CAIRO_STATUS_SUCCESS;    int i;    int min_x = INT16_MAX, max_x = INT16_MIN;    int	min_y = INT16_MAX, max_y = INT16_MAX;    if (scaled_font->status)	return scaled_font->status;    for (i = 0; i < num_glyphs; i++) {	cairo_scaled_glyph_t	*scaled_glyph;	int			left, top;	int			right, bottom;	int			x, y;	status = _cairo_scaled_glyph_lookup (scaled_font,					     glyphs[i].index,					     CAIRO_SCALED_GLYPH_INFO_METRICS,					     &scaled_glyph);	if (status) {	    _cairo_scaled_font_set_error (scaled_font, status);	    return status;	}	/* glyph images are snapped to pixel locations */	x = (int) floor (glyphs[i].x + 0.5);	y = (int) floor (glyphs[i].y + 0.5);	left   = x + _cairo_fixed_integer_floor(scaled_glyph->bbox.p1.x);	top    = y + _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y);	right  = x + _cairo_fixed_integer_ceil(scaled_glyph->bbox.p2.x);	bottom = y + _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.y);	if (left < min_x) min_x = left;	if (right > max_x) max_x = right;	if (top < min_y) min_y = top;	if (bottom > max_y) max_y = bottom;    }    if (min_x < max_x && min_y < max_y) {	extents->x = min_x;	extents->width = max_x - min_x;	extents->y = min_y;	extents->height = max_y - min_y;    } else {	extents->x = extents->y = 0;	extents->width = extents->height = 0;    }    return CAIRO_STATUS_SUCCESS;}cairo_status_t_cairo_scaled_font_show_glyphs (cairo_scaled_font_t    *scaled_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){    cairo_status_t status;    cairo_surface_t *mask = NULL;    int i;    /* These operators aren't interpreted the same way by the backends;     * they are implemented in terms of other operators in cairo-gstate.c     */    assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);    if (scaled_font->status)	return scaled_font->status;    if (scaled_font->backend->show_glyphs != NULL) {	status = scaled_font->backend->show_glyphs (scaled_font,						    op, pattern,						    surface,						    source_x, source_y,						    dest_x, dest_y,						    width, height,						    glyphs, num_glyphs);	if (status != CAIRO_INT_STATUS_UNSUPPORTED)	    return status;    }    /* Font display routine either does not exist or failed. */    status = CAIRO_STATUS_SUCCESS;    _cairo_cache_freeze (scaled_font->glyphs);    for (i = 0; i < num_glyphs; i++) {	int x, y;	cairo_surface_pattern_t glyph_pattern;	cairo_image_surface_t *glyph_surface;	cairo_scaled_glyph_t *scaled_glyph;	status = _cairo_scaled_glyph_lookup (scaled_font,

⌨️ 快捷键说明

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