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

📄 cairo-win32-font.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (scaled_font->quality == CLEARTYPE_QUALITY) {	    /* For ClearType, we need a 4-channel mask. If we are compositing on	     * a surface with alpha, we need to compute the alpha channel of	     * the mask (we just copy the green channel). But for a destination	     * surface without alpha the alpha channel of the mask is ignored	     */	    if (surface->format != CAIRO_FORMAT_RGB24)		_compute_argb32_mask_alpha (tmp_surface);	    else		_invert_argb32_mask (tmp_surface);	    mask_surface = &tmp_surface->base;	    /* XXX: Hacky, should expose this in cairo_image_surface */	    pixman_image_set_component_alpha (((cairo_image_surface_t *)tmp_surface->image)->pixman_image, TRUE);	} else {	    mask_surface = _compute_a8_mask (tmp_surface);	    cairo_surface_destroy (&tmp_surface->base);	    if (!mask_surface)		return CAIRO_STATUS_NO_MEMORY;	}	/* For op == OVER, no-cleartype, a possible optimization here is to	 * draw onto an intermediate ARGB32 surface and alpha-blend that with the	 * destination	 */	_cairo_pattern_init_for_surface (&mask, mask_surface);	status = _cairo_surface_composite (op, pattern,					   &mask.base,					   &surface->base,					   source_x, source_y,					   0, 0,					   dest_x, dest_y,					   width, height);	_cairo_pattern_fini (&mask.base);	cairo_surface_destroy (mask_surface);	return status;    }}static cairo_fixed_t_cairo_fixed_from_FIXED (FIXED f){    return *((cairo_fixed_t *)&f);}static cairo_status_t_cairo_win32_scaled_font_init_glyph_path (cairo_win32_scaled_font_t *scaled_font,					  cairo_scaled_glyph_t      *scaled_glyph){    static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, -1 } };    cairo_status_t status;    GLYPHMETRICS metrics;    HDC hdc;    DWORD bytesGlyph;    unsigned char *buffer, *ptr;    cairo_path_fixed_t *path;    hdc = _get_global_font_dc ();    if (!hdc)        return CAIRO_STATUS_NO_MEMORY;    path = _cairo_path_fixed_create ();    if (!path)	return CAIRO_STATUS_NO_MEMORY;    status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc);    if (status)        goto CLEANUP_PATH;    bytesGlyph = GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),				   GGO_NATIVE | GGO_GLYPH_INDEX,				   &metrics, 0, NULL, &matrix);    if (bytesGlyph == GDI_ERROR) {	status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");	goto CLEANUP_FONT;    }    ptr = buffer = malloc (bytesGlyph);    if (!buffer) {	status = CAIRO_STATUS_NO_MEMORY;	goto CLEANUP_FONT;    }    if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),			  GGO_NATIVE | GGO_GLYPH_INDEX,			  &metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) {	status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");	free (buffer);	goto CLEANUP_FONT;    }    while (ptr < buffer + bytesGlyph) {	TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)ptr;	unsigned char *endPoly = ptr + header->cb;	ptr += sizeof (TTPOLYGONHEADER);	_cairo_path_fixed_move_to (path,				   _cairo_fixed_from_FIXED (header->pfxStart.x),				   _cairo_fixed_from_FIXED (header->pfxStart.y));	while (ptr < endPoly) {	    TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;	    POINTFX *points = curve->apfx;	    int i;	    switch (curve->wType) {	    case TT_PRIM_LINE:		for (i = 0; i < curve->cpfx; i++) {		    _cairo_path_fixed_line_to (path,					       _cairo_fixed_from_FIXED (points[i].x),					       _cairo_fixed_from_FIXED (points[i].y));		}		break;	    case TT_PRIM_QSPLINE:		for (i = 0; i < curve->cpfx - 1; i++) {		    cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y;		    _cairo_path_fixed_get_current_point (path, &p1x, &p1y);		    cx = _cairo_fixed_from_FIXED (points[i].x);		    cy = _cairo_fixed_from_FIXED (points[i].y);		    if (i + 1 == curve->cpfx - 1) {			p2x = _cairo_fixed_from_FIXED (points[i + 1].x);			p2y = _cairo_fixed_from_FIXED (points[i + 1].y);		    } else {			/* records with more than one curve use interpolation for			   control points, per http://support.microsoft.com/kb/q87115/ */			p2x = (cx + _cairo_fixed_from_FIXED (points[i + 1].x)) / 2;			p2y = (cy + _cairo_fixed_from_FIXED (points[i + 1].y)) / 2;		    }		    c1x = 2 * cx / 3 + p1x / 3;		    c1y = 2 * cy / 3 + p1y / 3;		    c2x = 2 * cx / 3 + p2x / 3;		    c2y = 2 * cy / 3 + p2y / 3;		    _cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y);		}		break;	    case TT_PRIM_CSPLINE:		for (i = 0; i < curve->cpfx - 2; i += 2) {		    _cairo_path_fixed_curve_to (path,						_cairo_fixed_from_FIXED (points[i].x),						_cairo_fixed_from_FIXED (points[i].y),						_cairo_fixed_from_FIXED (points[i + 1].x),						_cairo_fixed_from_FIXED (points[i + 1].y),						_cairo_fixed_from_FIXED (points[i + 2].x),						_cairo_fixed_from_FIXED (points[i + 2].y));		}		break;	    }	    ptr += sizeof(TTPOLYCURVE) + sizeof (POINTFX) * (curve->cpfx - 1);	}	_cairo_path_fixed_close_path (path);    }    free(buffer);CLEANUP_FONT:    _cairo_scaled_glyph_set_path (scaled_glyph,				  &scaled_font->base,				  path);    cairo_win32_scaled_font_done_font (&scaled_font->base); CLEANUP_PATH:    if (status != CAIRO_STATUS_SUCCESS)	_cairo_path_fixed_destroy (path);    return status;}const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = {    CAIRO_FONT_TYPE_WIN32,    _cairo_win32_scaled_font_create_toy,    _cairo_win32_scaled_font_fini,    _cairo_win32_scaled_font_glyph_init,    _cairo_win32_scaled_font_text_to_glyphs,    NULL,			/* ucs4_to_index */    _cairo_win32_scaled_font_show_glyphs,};/* cairo_win32_font_face_t */typedef struct _cairo_win32_font_face cairo_win32_font_face_t;struct _cairo_win32_font_face {    cairo_font_face_t base;    LOGFONTW logfont;    HFONT hfont;};/* implement the platform-specific interface */static void_cairo_win32_font_face_destroy (void *abstract_face){}static cairo_status_t_cairo_win32_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 **font){    cairo_win32_font_face_t *font_face = abstract_face;    *font = _win32_scaled_font_create (&font_face->logfont,				       font_face->hfont,				       &font_face->base,				       font_matrix, ctm, options);    if (*font)	return CAIRO_STATUS_SUCCESS;    else	return CAIRO_STATUS_NO_MEMORY;}static const cairo_font_face_backend_t _cairo_win32_font_face_backend = {    CAIRO_FONT_TYPE_WIN32,    _cairo_win32_font_face_destroy,    _cairo_win32_font_face_scaled_font_create};/** * cairo_win32_font_face_create_for_logfontw: * @logfont: A #LOGFONTW structure specifying the font to use. *   The lfHeight, lfWidth, lfOrientation and lfEscapement *   fields of this structure are ignored. * * Creates a new font for the Win32 font backend based on a * #LOGFONT. 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 Win32 backend * and can be used with functions such as cairo_win32_scaled_font_select_font(). * * 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_win32_font_face_create_for_logfontw (LOGFONTW *logfont){    cairo_win32_font_face_t *font_face;    font_face = malloc (sizeof (cairo_win32_font_face_t));    if (!font_face) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_font_face_t *)&_cairo_font_face_nil;    }    font_face->logfont = *logfont;    font_face->hfont = NULL;    _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);    return &font_face->base;}/** * cairo_win32_font_face_create_for_hfont: * @font: An #HFONT structure specifying the font to use. * * Creates a new font for the Win32 font backend based on a * #HFONT. 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 Win32 backend * and can be used with functions such as cairo_win32_scaled_font_select_font(). * * 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_win32_font_face_create_for_hfont (HFONT font){    cairo_win32_font_face_t *font_face;    font_face = malloc (sizeof (cairo_win32_font_face_t));    if (!font_face) {	_cairo_error (CAIRO_STATUS_NO_MEMORY);	return (cairo_font_face_t *)&_cairo_font_face_nil;    }    font_face->hfont = font;    _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);    return &font_face->base;}/** * cairo_win32_scaled_font_select_font: * @scaled_font: A #cairo_scaled_font_t from the Win32 font backend. Such an *   object can be created with cairo_win32_scaled_font_create_for_logfontw(). * @hdc: a device context * * Selects the font into the given device context and changes the * map mode and world transformation of the device context to match * that of the font. This function is intended for use when using * layout APIs such as Uniscribe to do text layout with the * cairo font. After finishing using the device context, you must call * cairo_win32_scaled_font_done_font() to release any resources allocated * by this function. * * See cairo_win32_scaled_font_get_metrics_factor() for converting logical * coordinates from the device context to font space. * * Normally, calls to SaveDC() and RestoreDC() would be made around * the use of this function to preserve the original graphics state. * * Return value: %CAIRO_STATUS_SUCCESS if the operation succeeded. *   otherwise an error such as %CAIRO_STATUS_NO_MEMORY and *   the device context is unchanged. **/cairo_status_tcairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font,				     HDC                  hdc){    cairo_status_t status;    HFONT hfont;    HFONT old_hfont = NULL;    int old_mode;    if (scaled_font->status)	return scaled_font->status;    hfont = _win32_scaled_font_get_scaled_hfont ((cairo_win32_scaled_font_t *)scaled_font);    if (!hfont)	return CAIRO_STATUS_NO_MEMORY;    old_hfont = SelectObject (hdc, hfont);    if (!old_hfont)	return _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SelectObject");    old_mode = SetGraphicsMode (hdc, GM_ADVANCED);    if (!old_mode) {	status = _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SetGraphicsMode");	SelectObject (hdc, old_hfont);	return status;    }    status = _win32_scaled_font_set_world_transform ((cairo_win32_scaled_font_t *)scaled_font, hdc);    if (status) {	SetGraphicsMode (hdc, old_mode);	SelectObject (hdc, old_hfont);	return status;    }    SetMapMode (hdc, MM_TEXT);    return CAIRO_STATUS_SUCCESS;}/** * cairo_win32_scaled_font_done_font: * @scaled_font: A #cairo_scaled_font_t from the Win32 font backend. * * Releases any resources allocated by cairo_win32_scaled_font_select_font() **/voidcairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font){}/** * cairo_win32_scaled_font_get_metrics_factor: * @scaled_font: a #cairo_scaled_font_t from the Win32 font backend * * Gets a scale factor between logical coordinates in the coordinate * space used by cairo_win32_scaled_font_select_font() (that is, the * coordinate system used by the Windows functions to return metrics) and * font space coordinates. * * Return value: factor to multiply logical units by to get font space *               coordinates. **/doublecairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font){    return 1. / ((cairo_win32_scaled_font_t *)scaled_font)->logical_scale;}

⌨️ 快捷键说明

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