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

📄 cairo-win32-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 3 页
字号:
}static void_cairo_win32_surface_release_source_image (void                   *abstract_surface,					   cairo_image_surface_t  *image,					   void                   *image_extra){    cairo_win32_surface_t *local = image_extra;    if (local)	cairo_surface_destroy ((cairo_surface_t *)local);}static cairo_status_t_cairo_win32_surface_acquire_dest_image (void                    *abstract_surface,					 cairo_rectangle_int16_t *interest_rect,					 cairo_image_surface_t  **image_out,					 cairo_rectangle_int16_t *image_rect,					 void                   **image_extra){    cairo_win32_surface_t *surface = abstract_surface;    cairo_win32_surface_t *local = NULL;    cairo_status_t status;    RECT clip_box;    int x1, y1, x2, y2;    if (surface->image) {	GdiFlush();	image_rect->x = 0;	image_rect->y = 0;	image_rect->width = surface->clip_rect.width;	image_rect->height = surface->clip_rect.height;	*image_out = (cairo_image_surface_t *)surface->image;	*image_extra = NULL;	return CAIRO_STATUS_SUCCESS;    }    if (GetClipBox (surface->dc, &clip_box) == ERROR)	return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");    x1 = clip_box.left;    x2 = clip_box.right;    y1 = clip_box.top;    y2 = clip_box.bottom;    if (interest_rect->x > x1)	x1 = interest_rect->x;    if (interest_rect->y > y1)	y1 = interest_rect->y;    if (interest_rect->x + interest_rect->width < x2)	x2 = interest_rect->x + interest_rect->width;    if (interest_rect->y + interest_rect->height < y2)	y2 = interest_rect->y + interest_rect->height;    if (x1 >= x2 || y1 >= y2) {	*image_out = NULL;	*image_extra = NULL;	return CAIRO_STATUS_SUCCESS;    }    status = _cairo_win32_surface_get_subimage (abstract_surface,						x1, y1, x2 - x1, y2 - y1,						&local);    if (status)	return status;    *image_out = (cairo_image_surface_t *)local->image;    *image_extra = local;    image_rect->x = x1;    image_rect->y = y1;    image_rect->width = x2 - x1;    image_rect->height = y2 - y1;    return CAIRO_STATUS_SUCCESS;}static void_cairo_win32_surface_release_dest_image (void                    *abstract_surface,					 cairo_rectangle_int16_t *interest_rect,					 cairo_image_surface_t   *image,					 cairo_rectangle_int16_t *image_rect,					 void                    *image_extra){    cairo_win32_surface_t *surface = abstract_surface;    cairo_win32_surface_t *local = image_extra;    if (!local)	return;    if (!BitBlt (surface->dc,		 image_rect->x, image_rect->y,		 image_rect->width, image_rect->height,		 local->dc,		 0, 0,		 SRCCOPY))	_cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image");    cairo_surface_destroy ((cairo_surface_t *)local);}#if !defined(AC_SRC_OVER)#define AC_SRC_OVER                 0x00#pragma pack(1)typedef struct {    BYTE   BlendOp;    BYTE   BlendFlags;    BYTE   SourceConstantAlpha;    BYTE   AlphaFormat;}BLENDFUNCTION;#pragma pack()#endif/* for compatibility with VC++ 6 */#ifndef AC_SRC_ALPHA#define AC_SRC_ALPHA                0x01#endiftypedef BOOL (WINAPI *cairo_alpha_blend_func_t) (HDC hdcDest,						 int nXOriginDest,						 int nYOriginDest,						 int nWidthDest,						 int hHeightDest,						 HDC hdcSrc,						 int nXOriginSrc,						 int nYOriginSrc,						 int nWidthSrc,						 int nHeightSrc,						 BLENDFUNCTION blendFunction);static cairo_int_status_t_composite_alpha_blend (cairo_win32_surface_t *dst,			cairo_win32_surface_t *src,			int                    alpha,			int                    src_x,			int                    src_y,			int                    dst_x,			int                    dst_y,			int                    width,			int                    height){    static unsigned alpha_blend_checked = FALSE;    static cairo_alpha_blend_func_t alpha_blend = NULL;    BLENDFUNCTION blend_function;    /* Check for AlphaBlend dynamically to allow compiling on     * MSVC 6 and use on older windows versions     */    if (!alpha_blend_checked) {	OSVERSIONINFO os;	os.dwOSVersionInfoSize = sizeof (os);	GetVersionEx (&os);	/* If running on Win98, disable using AlphaBlend()	 * to avoid Win98 AlphaBlend() bug */	if (VER_PLATFORM_WIN32_WINDOWS != os.dwPlatformId ||	    os.dwMajorVersion != 4 || os.dwMinorVersion != 10)	{	    HMODULE msimg32_dll = LoadLibrary ("msimg32");	    if (msimg32_dll != NULL)		alpha_blend = (cairo_alpha_blend_func_t)GetProcAddress (msimg32_dll,									"AlphaBlend");	}	alpha_blend_checked = TRUE;    }    if (alpha_blend == NULL)	return CAIRO_INT_STATUS_UNSUPPORTED;    if (GetDeviceCaps(dst->dc, SHADEBLENDCAPS) == SB_NONE)	return CAIRO_INT_STATUS_UNSUPPORTED;    blend_function.BlendOp = AC_SRC_OVER;    blend_function.BlendFlags = 0;    blend_function.SourceConstantAlpha = alpha;    blend_function.AlphaFormat = src->format == CAIRO_FORMAT_ARGB32 ? AC_SRC_ALPHA : 0;    if (!alpha_blend (dst->dc,		      dst_x, dst_y,		      width, height,		      src->dc,		      src_x, src_y,		      width, height,		      blend_function))	return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_win32_surface_composite (cairo_operator_t	op,				cairo_pattern_t       	*pattern,				cairo_pattern_t		*mask_pattern,				void			*abstract_dst,				int			src_x,				int			src_y,				int			mask_x,				int			mask_y,				int			dst_x,				int			dst_y,				unsigned int		width,				unsigned int		height){    cairo_win32_surface_t *dst = abstract_dst;    cairo_win32_surface_t *src;    cairo_surface_pattern_t *src_surface_pattern;    int alpha;    int integer_transform;    int itx, ity;    if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE ||	pattern->extend != CAIRO_EXTEND_NONE)	return CAIRO_INT_STATUS_UNSUPPORTED;    if (mask_pattern) {	/* FIXME: When we fully support RENDER style 4-channel	 * masks we need to check r/g/b != 1.0.	 */	if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID)	    return CAIRO_INT_STATUS_UNSUPPORTED;	alpha = ((cairo_solid_pattern_t *)mask_pattern)->color.alpha_short >> 8;    } else {        alpha = 255;    }    src_surface_pattern = (cairo_surface_pattern_t *)pattern;    src = (cairo_win32_surface_t *)src_surface_pattern->surface;    if (src->base.backend != dst->base.backend)	return CAIRO_INT_STATUS_UNSUPPORTED;    integer_transform = _cairo_matrix_is_integer_translation (&pattern->matrix, &itx, &ity);    if (!integer_transform)	return CAIRO_INT_STATUS_UNSUPPORTED;    /* Fix up src coordinates; the src coords and size must be within the     * bounds of the source surface.     * XXX the region not covered should be appropriately rendered!     * - for OVER/SOURCE with RGB24 source -> opaque black     * - for SOURCE with ARGB32 source -> 100% transparent black     */    src_x += itx;    src_y += ity;    if (src_x < 0) {        width += src_x;        dst_x -= src_x;        src_x = 0;    }    if (src_y < 0) {        height += src_y;        dst_y -= src_y;        src_y = 0;    }    if (src_x + width > src->extents.width)        width = src->extents.width - src_x;    if (src_y + height > src->extents.height)        height = src->extents.height - src_y;    if (alpha == 255 &&	(op == CAIRO_OPERATOR_SOURCE ||	 (src->format == CAIRO_FORMAT_RGB24 && op == CAIRO_OPERATOR_OVER))) {	if (!BitBlt (dst->dc,		     dst_x, dst_y,		     width, height,		     src->dc,		     src_x, src_y,		     SRCCOPY))	    return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");	return CAIRO_STATUS_SUCCESS;    } else if ((src->format == CAIRO_FORMAT_RGB24 || src->format == CAIRO_FORMAT_ARGB32) &&	       (dst->format == CAIRO_FORMAT_RGB24 || dst->format == CAIRO_FORMAT_ARGB32) &&	       op == CAIRO_OPERATOR_OVER) {	return _composite_alpha_blend (dst, src, alpha,				       src_x, src_y,				       dst_x, dst_y, width, height);    }    return CAIRO_INT_STATUS_UNSUPPORTED;}/* This big function tells us how to optimize operators for the * case of solid destination and constant-alpha source * * NOTE: This function needs revisiting if we add support for *       super-luminescent colors (a == 0, r,g,b > 0) */static enum { DO_CLEAR, DO_SOURCE, DO_NOTHING, DO_UNSUPPORTED }categorize_solid_dest_operator (cairo_operator_t op,				unsigned short   alpha){    enum { SOURCE_TRANSPARENT, SOURCE_LIGHT, SOURCE_SOLID, SOURCE_OTHER } source;    if (alpha >= 0xff00)	source = SOURCE_SOLID;    else if (alpha < 0x100)	source = SOURCE_TRANSPARENT;    else	source = SOURCE_OTHER;    switch (op) {    case CAIRO_OPERATOR_CLEAR:    /* 0                 0 */    case CAIRO_OPERATOR_OUT:      /* 1 - Ab            0 */	return DO_CLEAR;	break;    case CAIRO_OPERATOR_SOURCE:   /* 1                 0 */    case CAIRO_OPERATOR_IN:       /* Ab                0 */	return DO_SOURCE;	break;    case CAIRO_OPERATOR_OVER:     /* 1            1 - Aa */    case CAIRO_OPERATOR_ATOP:     /* Ab           1 - Aa */	if (source == SOURCE_SOLID)	    return DO_SOURCE;	else if (source == SOURCE_TRANSPARENT)	    return DO_NOTHING;	else	    return DO_UNSUPPORTED;	break;    case CAIRO_OPERATOR_DEST_OUT: /* 0            1 - Aa */    case CAIRO_OPERATOR_XOR:      /* 1 - Ab       1 - Aa */	if (source == SOURCE_SOLID)	    return DO_CLEAR;	else if (source == SOURCE_TRANSPARENT)	    return DO_NOTHING;	else	    return DO_UNSUPPORTED;    	break;    case CAIRO_OPERATOR_DEST:     /* 0                 1 */    case CAIRO_OPERATOR_DEST_OVER:/* 1 - Ab            1 */    case CAIRO_OPERATOR_SATURATE: /* min(1,(1-Ab)/Aa)  1 */	return DO_NOTHING;	break;    case CAIRO_OPERATOR_DEST_IN:  /* 0                Aa */    case CAIRO_OPERATOR_DEST_ATOP:/* 1 - Ab           Aa */	if (source == SOURCE_SOLID)	    return DO_NOTHING;	else if (source == SOURCE_TRANSPARENT)	    return DO_CLEAR;	else	    return DO_UNSUPPORTED;	break;    case CAIRO_OPERATOR_ADD:	  /* 1                1 */	if (source == SOURCE_TRANSPARENT)	    return DO_NOTHING;	else	    return DO_UNSUPPORTED;	break;    }    ASSERT_NOT_REACHED;    return DO_UNSUPPORTED;}static cairo_int_status_t_cairo_win32_surface_fill_rectangles (void			*abstract_surface,				      cairo_operator_t		op,				      const cairo_color_t	*color,				      cairo_rectangle_int16_t		*rects,				      int			num_rects){    cairo_win32_surface_t *surface = abstract_surface;    cairo_status_t status;    COLORREF new_color;    HBRUSH new_brush;    int i;    /* XXXperf If it's not RGB24, we need to do a little more checking     * to figure out when we can use GDI.  We don't have that checking     * anywhere at the moment, so just bail and use the fallback     * paths. */    if (surface->format != CAIRO_FORMAT_RGB24)	return CAIRO_INT_STATUS_UNSUPPORTED;    /* Optimize for no destination alpha (surface->pixman_image is non-NULL for all     * surfaces with alpha.)     */    switch (categorize_solid_dest_operator (op, color->alpha_short)) {    case DO_CLEAR:	new_color = RGB (0, 0, 0);	break;    case DO_SOURCE:	new_color = RGB (color->red_short >> 8, color->green_short >> 8, color->blue_short >> 8);	break;    case DO_NOTHING:	return CAIRO_STATUS_SUCCESS;    case DO_UNSUPPORTED:    default:	return CAIRO_INT_STATUS_UNSUPPORTED;    }    new_brush = CreateSolidBrush (new_color);    if (!new_brush)	return _cairo_win32_print_gdi_error ("_cairo_win32_surface_fill_rectangles");    for (i = 0; i < num_rects; i++) {	RECT rect;	rect.left = rects[i].x;	rect.top = rects[i].y;	rect.right = rects[i].x + rects[i].width;	rect.bottom = rects[i].y + rects[i].height;	if (!FillRect (surface->dc, &rect, new_brush))	    goto FAIL;    }    DeleteObject (new_brush);    return CAIRO_STATUS_SUCCESS; FAIL:    status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_fill_rectangles");    DeleteObject (new_brush);

⌨️ 快捷键说明

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