📄 cairo-directfb-surface.c
字号:
surface = calloc (1, sizeof(cairo_directfb_surface_t)); if (!surface) return NULL; surface->surface = _directfb_buffer_surface_create (source->dfb, cairo_to_directfb_format (format), MAX (width, 8), MAX (height, 8) ); if (!surface->surface) { free (surface); return NULL; } _cairo_surface_init (&surface->base, &cairo_directfb_surface_backend,content); source->dfb->AddRef (source->dfb); surface->dfb = source->dfb; surface->surface->AddRef (surface->surface); surface->buffer = surface->surface; surface->format = format; surface->width = width; surface->height = height; surface->local = true; return &surface->base;}static cairo_status_t_cairo_directfb_surface_finish (void *data){ cairo_directfb_surface_t *surface = (cairo_directfb_surface_t *)data; D_DEBUG_AT (Cairo_DirectFB, "%s( surface=%p ).\n", __FUNCTION__, surface); if (surface->buffer_image) { cairo_surface_destroy (surface->buffer_image); surface->buffer_image = NULL; } if (surface->clips) { free (surface->clips); surface->clips = NULL; surface->n_clips = 0; } if (surface->color) { cairo_surface_destroy (surface->color); surface->color = NULL; } if (surface->buffer) { surface->buffer->Release (surface->buffer); surface->buffer = NULL; } if (surface->surface) { surface->surface->Release (surface->surface); surface->surface = NULL; } if (surface->dfb) { surface->dfb->Release (surface->dfb); surface->dfb = NULL; } return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_directfb_surface_acquire_source_image (void *abstract_surface, cairo_image_surface_t **image_out, void **image_extra){ cairo_directfb_surface_t *surface = abstract_surface; cairo_status_t ret; D_DEBUG_AT (Cairo_DirectFB, "%s( surface=%p ).\n", __FUNCTION__, surface); ret = _directfb_acquire_surface (surface, DSLF_READ); if (ret) return ret; if (image_out) *image_out = (cairo_image_surface_t *)surface->buffer_image; if (image_extra) *image_extra = surface; return CAIRO_STATUS_SUCCESS;}static void_cairo_directfb_surface_release_source_image (void *abstract_surface, cairo_image_surface_t *image, void *image_extra){ cairo_directfb_surface_t *surface = abstract_surface; D_DEBUG_AT (Cairo_DirectFB, "%s( surface=%p ).\n", __FUNCTION__, surface); surface->buffer->Unlock (surface->buffer);}static cairo_status_t_cairo_directfb_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_out, void **image_extra){ cairo_directfb_surface_t *surface = abstract_surface; cairo_status_t ret; D_DEBUG_AT (Cairo_DirectFB, "%s( surface=%p ).\n", __FUNCTION__, surface); ret = _directfb_acquire_surface (surface, DSLF_READ | DSLF_WRITE); if (ret) return ret; if (image_out) *image_out = (cairo_image_surface_t *)surface->buffer_image; if (image_rect_out) { image_rect_out->x = 0; image_rect_out->y = 0; image_rect_out->width = surface->width; image_rect_out->height = surface->height; } if (image_extra) *image_extra = interest_rect; return CAIRO_STATUS_SUCCESS;}static void_cairo_directfb_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_directfb_surface_t *surface = abstract_surface; D_DEBUG_AT (Cairo_DirectFB, "%s( surface=%p ).\n", __FUNCTION__, surface); surface->buffer->Unlock (surface->buffer);}static cairo_status_t_cairo_directfb_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, cairo_surface_t **clone_out){ cairo_directfb_surface_t *surface = abstract_surface; cairo_directfb_surface_t *clone; D_DEBUG_AT (Cairo_DirectFB, "%s( surface=%p, src=%p ).\n", __FUNCTION__, surface, src); if (src->backend == surface->base.backend) { cairo_surface_reference (src); *clone_out = src; return CAIRO_STATUS_SUCCESS; } else if (_cairo_surface_is_image (src)) { cairo_image_surface_t *image_src = (cairo_image_surface_t *) src; unsigned char *dst, *src = image_src->data; int pitch; int i, j; DFBResult ret; clone = (cairo_directfb_surface_t *) _cairo_directfb_surface_create_similar (surface, _cairo_content_from_format (image_src->format), image_src->width, image_src->height); if (!clone) return CAIRO_STATUS_NO_MEMORY; ret = clone->buffer->Lock (clone->buffer, DSLF_WRITE, (void *)&dst, &pitch); if (ret) { DirectFBError ("IDirectFBSurface::Lock()", ret); cairo_surface_destroy ((cairo_surface_t *)clone); return CAIRO_STATUS_NO_MEMORY; } if (image_src->format == CAIRO_FORMAT_A1) { /* A1 -> A8 */ for (i = 0; i < image_src->height; i++) { for (j = 0; j < image_src->width; j++) dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0x00; dst += pitch; src += image_src->stride; } } else { for (i = 0; i < image_src->height; i++) { direct_memcpy( dst, src, image_src->stride ); dst += pitch; src += image_src->stride; } } clone->buffer->Unlock (clone->buffer); *clone_out = &clone->base; return CAIRO_STATUS_SUCCESS; } return CAIRO_INT_STATUS_UNSUPPORTED;}#if DFB_COMPOSITE || DFB_COMPOSITE_TRAPEZOIDSstatic cairo_int_status_t_directfb_prepare_composite (cairo_directfb_surface_t *dst, cairo_pattern_t *src_pattern, cairo_pattern_t *mask_pattern, cairo_operator_t op, int *src_x, int *src_y, int *mask_x, int *mask_y, unsigned int width, unsigned int height, cairo_directfb_surface_t **ret_src, cairo_surface_attributes_t *ret_src_attr){ cairo_directfb_surface_t *src; cairo_surface_attributes_t src_attr; cairo_status_t ret; DFBSurfaceBlittingFlags flags; DFBSurfaceBlendFunction sblend; DFBSurfaceBlendFunction dblend; DFBColor color; if (_directfb_get_operator (op, NULL, &flags, &sblend, &dblend)) return CAIRO_INT_STATUS_UNSUPPORTED; if (mask_pattern) { cairo_solid_pattern_t *pattern; if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID) { cairo_pattern_t *tmp; int tmp_x, tmp_y; if (src_pattern->type != CAIRO_PATTERN_TYPE_SOLID || sblend == DSBF_INVDESTALPHA) /* Doesn't work correctly */ return CAIRO_INT_STATUS_UNSUPPORTED; D_DEBUG_AT (Cairo_DirectFB, "Replacing src pattern by mask pattern.\n"); tmp = src_pattern; tmp_x = *src_x; tmp_y = *src_y; src_pattern = mask_pattern; *src_x = *mask_x; *src_y = *mask_y; mask_pattern = tmp; *mask_x = tmp_x; *mask_y = tmp_y; if (sblend == DSBF_ONE) { flags |= DSBLIT_BLEND_ALPHACHANNEL; sblend = DSBF_SRCALPHA; //dblend = DSBF_INVSRCALPHA; } } pattern = (cairo_solid_pattern_t *)mask_pattern; color.a = pattern->color.alpha_short >> 8; color.r = pattern->color.red_short >> 8; color.g = pattern->color.green_short >> 8; color.b = pattern->color.blue_short >> 8; } else { color.a = color.r = color.g = color.b = 0xff; } ret = _directfb_acquire_surface (dst, 0); if (ret) return ret; if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) { cairo_solid_pattern_t *pattern = (cairo_solid_pattern_t *)src_pattern; if (!dst->color) { dst->color = _cairo_directfb_surface_create_similar (dst, CAIRO_CONTENT_COLOR_ALPHA, 1, 1); if (!dst->color) return CAIRO_STATUS_NO_MEMORY; } src = (cairo_directfb_surface_t *)dst->color; src->buffer->SetColor (src->buffer, pattern->color.red_short >> 8, pattern->color.green_short >> 8, pattern->color.blue_short >> 8, pattern->color.alpha_short >> 8); src->buffer->FillRectangle (src->buffer, 0, 0, 1, 1); cairo_matrix_init_identity (&src_attr.matrix); src_attr.matrix = src_pattern->matrix; src_attr.extend = CAIRO_EXTEND_NONE; src_attr.filter = CAIRO_FILTER_NEAREST; src_attr.x_offset = src_attr.y_offset = 0; } else { ret = _cairo_pattern_acquire_surface (src_pattern, &dst->base, *src_x, *src_y, width, height, (cairo_surface_t **)&src, &src_attr); if (ret) return ret; ret = _directfb_acquire_surface (src, 0); if (ret) { _cairo_pattern_release_surface (src_pattern, &src->base, &src_attr); return ret; } } if (color.a != 0xff) flags |= DSBLIT_BLEND_COLORALPHA; if (color.r != 0xff || color.g != 0xff || color.b != 0xff) flags |= DSBLIT_COLORIZE; dst->buffer->SetBlittingFlags (dst->buffer, flags); if (flags & (DSBLIT_BLEND_COLORALPHA | DSBLIT_BLEND_ALPHACHANNEL)) { dst->buffer->SetSrcBlendFunction (dst->buffer, sblend); dst->buffer->SetDstBlendFunction (dst->buffer, dblend); } if (flags & (DSBLIT_BLEND_COLORALPHA | DSBLIT_COLORIZE)) dst->buffer->SetColor (dst->buffer, color.r, color.g, color.b, color.a); *ret_src = src; *ret_src_attr = src_attr; return CAIRO_STATUS_SUCCESS;}static void_directfb_finish_composite (cairo_directfb_surface_t *dst, cairo_pattern_t *src_pattern, cairo_surface_t *src, cairo_surface_attributes_t *src_attr){ if (src != dst->color) _cairo_pattern_release_surface (src_pattern, src, src_attr);}#endif /* DFB_COMPOSITE || DFB_COMPOSITE_TRAPEZOIDS */ #if DFB_COMPOSITEstatic cairo_int_status_t_cairo_directfb_surface_composite (cairo_operator_t op, cairo_pattern_t *src_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_directfb_surface_t *dst = abstract_dst; cairo_directfb_surface_t *src; cairo_surface_attributes_t src_attr; cairo_matrix_t *m; cairo_status_t ret; D_DEBUG_AT (Cairo_DirectFB, "%s( op=%d, src_pattern=%p, mask_pattern=%p, dst=%p," " src_x=%d, src_y=%d, mask_x=%d, mask_y=%d, dst_x=%d," " dst_y=%d, width=%u, height=%u ).\n", __FUNCTION__, op, src_pattern, mask_pattern, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); ret = _directfb_prepare_composite (dst, src_pattern, mask_pattern, op, &src_x, &src_y, &mask_x, &mask_y, width, height, &src, &src_attr); if (ret) return ret; ret = CAIRO_INT_STATUS_UNSUPPORTED; m = &src_attr.matrix; if (_cairo_matrix_is_integer_translation (m, NULL, NULL)) { DFBRectangle sr; sr.x = src_x + src_attr.x_offset; sr.y = src_y + src_attr.y_offset; sr.w = src->width - sr.x; sr.h = src->height - sr.y; if (src_attr.extend == CAIRO_EXTEND_NONE) { D_DEBUG_AT (Cairo_DirectFB, "Running Blit().\n"); RUN_CLIPPED( dst, NULL, dst->buffer->Blit (dst->buffer, src->buffer, &sr, dst_x, dst_y)); ret = CAIRO_STATUS_SUCCESS; } else if (src_attr.extend == CAIRO_EXTEND_REPEAT) { DFBRegion clip; clip.x1 = dst_x; clip.y1 = dst_y; clip.x2 = dst_x + width - 1; clip.y2 = dst_y + height - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -