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

📄 cairo-win32-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * of the font.	 */	status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc);	if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),			      GGO_METRICS | GGO_GLYPH_INDEX,			      &metrics, 0, NULL, &matrix) == GDI_ERROR) {	  status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetGlyphOutlineW");	  memset (&metrics, 0, sizeof (GLYPHMETRICS));	}	_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);	extents.x_bearing = (double)metrics.gmptGlyphOrigin.x / scaled_font->em_square;	extents.y_bearing = - (double)metrics.gmptGlyphOrigin.y / scaled_font->em_square;	extents.width = (double)metrics.gmBlackBoxX / scaled_font->em_square;	extents.height = (double)metrics.gmBlackBoxY / scaled_font->em_square;	extents.x_advance = (double)metrics.gmCellIncX / scaled_font->em_square;	extents.y_advance = (double)metrics.gmCellIncY / scaled_font->em_square;    }    _cairo_scaled_glyph_set_metrics (scaled_glyph,				     &scaled_font->base,				     &extents);    return CAIRO_STATUS_SUCCESS;}/* Not currently used code, but may be useful in the future if we add * back the capability to the scaled font backend interface to get the * actual device space bbox rather than computing it from the * font-space metrics. */#if 0static cairo_status_t_cairo_win32_scaled_font_glyph_bbox (void		 *abstract_font,				     const cairo_glyph_t *glyphs,				     int                  num_glyphs,				     cairo_box_t         *bbox){    static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };    cairo_win32_scaled_font_t *scaled_font = abstract_font;    int x1 = 0, x2 = 0, y1 = 0, y2 = 0;    if (num_glyphs > 0) {	HDC hdc = _get_global_font_dc ();	GLYPHMETRICS metrics;	cairo_status_t status;	int i;	if (!hdc)	    return CAIRO_STATUS_NO_MEMORY;	status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);	if (status)	    return status;	for (i = 0; i < num_glyphs; i++) {	    int x = floor (0.5 + glyphs[i].x);	    int y = floor (0.5 + glyphs[i].y);	    GetGlyphOutlineW (hdc, glyphs[i].index, GGO_METRICS | GGO_GLYPH_INDEX,			     &metrics, 0, NULL, &matrix);	    if (i == 0 || x1 > x + metrics.gmptGlyphOrigin.x)		x1 = x + metrics.gmptGlyphOrigin.x;	    if (i == 0 || y1 > y - metrics.gmptGlyphOrigin.y)		y1 = y - metrics.gmptGlyphOrigin.y;	    if (i == 0 || x2 < x + metrics.gmptGlyphOrigin.x + (int)metrics.gmBlackBoxX)		x2 = x + metrics.gmptGlyphOrigin.x + (int)metrics.gmBlackBoxX;	    if (i == 0 || y2 < y - metrics.gmptGlyphOrigin.y + (int)metrics.gmBlackBoxY)		y2 = y - metrics.gmptGlyphOrigin.y + (int)metrics.gmBlackBoxY;	}	cairo_win32_scaled_font_done_font (&scaled_font->base);    }    bbox->p1.x = _cairo_fixed_from_int (x1);    bbox->p1.y = _cairo_fixed_from_int (y1);    bbox->p2.x = _cairo_fixed_from_int (x2);    bbox->p2.y = _cairo_fixed_from_int (y2);    return CAIRO_STATUS_SUCCESS;}#endiftypedef struct {    cairo_win32_scaled_font_t *scaled_font;    HDC hdc;    cairo_array_t glyphs;    cairo_array_t dx;    int start_x;    int last_x;    int last_y;} cairo_glyph_state_t;static void_start_glyphs (cairo_glyph_state_t        *state,	       cairo_win32_scaled_font_t  *scaled_font,	       HDC                         hdc){    state->hdc = hdc;    state->scaled_font = scaled_font;    _cairo_array_init (&state->glyphs, sizeof (WCHAR));    _cairo_array_init (&state->dx, sizeof (int));}static cairo_status_t_flush_glyphs (cairo_glyph_state_t *state){    cairo_status_t status;    int dx = 0;    WCHAR * elements;    int * dx_elements;    status = _cairo_array_append (&state->dx, &dx);    if (status)	return status;    elements = _cairo_array_index (&state->glyphs, 0);    dx_elements = _cairo_array_index (&state->dx, 0);    if (!ExtTextOutW (state->hdc,		      state->start_x, state->last_y,		      ETO_GLYPH_INDEX,		      NULL,		      elements,		      state->glyphs.num_elements,		      dx_elements)) {	return _cairo_win32_print_gdi_error ("_flush_glyphs");    }    _cairo_array_truncate (&state->glyphs, 0);    _cairo_array_truncate (&state->dx, 0);    return CAIRO_STATUS_SUCCESS;}static cairo_status_t_add_glyph (cairo_glyph_state_t *state,	    unsigned long        index,	    double               device_x,	    double               device_y){    cairo_status_t status;    double user_x = device_x;    double user_y = device_y;    WCHAR glyph_index = index;    int logical_x, logical_y;    cairo_matrix_transform_point (&state->scaled_font->device_to_logical, &user_x, &user_y);    logical_x = floor (user_x + 0.5);    logical_y = floor (user_y + 0.5);    if (state->glyphs.num_elements > 0) {	int dx;	if (logical_y != state->last_y) {	    status = _flush_glyphs (state);	    if (status)		return status;	    state->start_x = logical_x;	}	dx = logical_x - state->last_x;	status = _cairo_array_append (&state->dx, &dx);	if (status)	    return status;    } else {	state->start_x = logical_x;    }    state->last_x = logical_x;    state->last_y = logical_y;    status = _cairo_array_append (&state->glyphs, &glyph_index);    if (status)	return status;    return CAIRO_STATUS_SUCCESS;}static void_finish_glyphs (cairo_glyph_state_t *state){    _flush_glyphs (state);    _cairo_array_fini (&state->glyphs);    _cairo_array_fini (&state->dx);}static cairo_status_t_draw_glyphs_on_surface (cairo_win32_surface_t     *surface,			 cairo_win32_scaled_font_t *scaled_font,			 COLORREF                   color,			 int                        x_offset,			 int                        y_offset,			 const cairo_glyph_t       *glyphs,			 int                 	    num_glyphs){    cairo_glyph_state_t state;    cairo_status_t status = CAIRO_STATUS_SUCCESS;    int i;    if (!SaveDC (surface->dc))	return _cairo_win32_print_gdi_error ("_draw_glyphs_on_surface:SaveDC");    status = cairo_win32_scaled_font_select_font (&scaled_font->base, surface->dc);    if (status)	goto FAIL1;    SetTextColor (surface->dc, color);    SetTextAlign (surface->dc, TA_BASELINE | TA_LEFT);    SetBkMode (surface->dc, TRANSPARENT);    _start_glyphs (&state, scaled_font, surface->dc);    for (i = 0; i < num_glyphs; i++) {	status = _add_glyph (&state, glyphs[i].index,			     glyphs[i].x - x_offset, glyphs[i].y - y_offset);	if (status)	    goto FAIL2;    } FAIL2:    _finish_glyphs (&state);    cairo_win32_scaled_font_done_font (&scaled_font->base); FAIL1:    RestoreDC (surface->dc, -1);    return status;}/* Duplicate the green channel of a 4-channel mask in the alpha channel, then * invert the whole mask. */static void_compute_argb32_mask_alpha (cairo_win32_surface_t *mask_surface){    cairo_image_surface_t *image = (cairo_image_surface_t *)mask_surface->image;    int i, j;    for (i = 0; i < image->height; i++) {	uint32_t *p = (uint32_t *) (image->data + i * image->stride);	for (j = 0; j < image->width; j++) {	    *p = 0xffffffff ^ (*p | ((*p & 0x0000ff00) << 16));	    p++;	}    }}/* Invert a mask */static void_invert_argb32_mask (cairo_win32_surface_t *mask_surface){    cairo_image_surface_t *image = (cairo_image_surface_t *)mask_surface->image;    int i, j;    for (i = 0; i < image->height; i++) {	uint32_t *p = (uint32_t *) (image->data + i * image->stride);	for (j = 0; j < image->width; j++) {	    *p = 0xffffffff ^ *p;	    p++;	}    }}/* Compute an alpha-mask from a monochrome RGB24 image */static cairo_surface_t *_compute_a8_mask (cairo_win32_surface_t *mask_surface){    cairo_image_surface_t *image24 = (cairo_image_surface_t *)mask_surface->image;    cairo_image_surface_t *image8;    int i, j;    image8 = (cairo_image_surface_t *)cairo_image_surface_create (CAIRO_FORMAT_A8,								  image24->width, image24->height);    if (image8->base.status)	return NULL;    for (i = 0; i < image24->height; i++) {	uint32_t *p = (uint32_t *) (image24->data + i * image24->stride);	unsigned char *q = (unsigned char *) (image8->data + i * image8->stride);	for (j = 0; j < image24->width; j++) {	    *q = 255 - ((*p & 0x0000ff00) >> 8);	    p++;	    q++;	}    }    return &image8->base;}static cairo_status_t_cairo_win32_scaled_font_glyph_init (void		       *abstract_font,				     cairo_scaled_glyph_t      *scaled_glyph,				     cairo_scaled_glyph_info_t  info){    cairo_win32_scaled_font_t *scaled_font = abstract_font;    cairo_status_t status;    if ((info & CAIRO_SCALED_GLYPH_INFO_METRICS) != 0) {	status = _cairo_win32_scaled_font_init_glyph_metrics (scaled_font, scaled_glyph);	if (status)	    return status;    }    if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {	ASSERT_NOT_REACHED;    }    if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0) {	status = _cairo_win32_scaled_font_init_glyph_path (scaled_font, scaled_glyph);	if (status)	    return status;    }    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_win32_scaled_font_show_glyphs (void		       *abstract_font,				      cairo_operator_t    	op,				      cairo_pattern_t          *pattern,				      cairo_surface_t          *generic_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_win32_scaled_font_t *scaled_font = abstract_font;    cairo_win32_surface_t *surface = (cairo_win32_surface_t *)generic_surface;    cairo_status_t status;    if (width == 0 || height == 0)	return CAIRO_STATUS_SUCCESS;    if (_cairo_surface_is_win32 (generic_surface) &&	surface->format == CAIRO_FORMAT_RGB24 &&	op == CAIRO_OPERATOR_OVER &&	_cairo_pattern_is_opaque_solid (pattern)) {	cairo_solid_pattern_t *solid_pattern = (cairo_solid_pattern_t *)pattern;	/* When compositing OVER on a GDI-understood surface, with a	 * solid opaque color, we can just call ExtTextOut directly.	 */	COLORREF new_color;	new_color = RGB (((int)solid_pattern->color.red_short) >> 8,			 ((int)solid_pattern->color.green_short) >> 8,			 ((int)solid_pattern->color.blue_short) >> 8);	status = _draw_glyphs_on_surface (surface, scaled_font, new_color,					  0, 0,					  glyphs, num_glyphs);	return status;    } else {	/* Otherwise, we need to draw using software fallbacks. We create a mask	 * surface by drawing the the glyphs onto a DIB, black-on-white then	 * inverting. GDI outputs gamma-corrected images so inverted black-on-white	 * is very different from white-on-black. We favor the more common	 * case where the final output is dark-on-light.	 */	cairo_win32_surface_t *tmp_surface;	cairo_surface_t *mask_surface;	cairo_surface_pattern_t mask;	RECT r;	tmp_surface = (cairo_win32_surface_t *)cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, width, height);	if (tmp_surface->base.status)	    return CAIRO_STATUS_NO_MEMORY;	r.left = 0;	r.top = 0;	r.right = width;	r.bottom = height;	FillRect (tmp_surface->dc, &r, GetStockObject (WHITE_BRUSH));	_draw_glyphs_on_surface (tmp_surface, scaled_font, RGB (0, 0, 0),				 dest_x, dest_y,				 glyphs, num_glyphs);

⌨️ 快捷键说明

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