Пример #1
0
static cairo_status_t
_cairo_beos_surface_acquire_source_image (void                   *abstract_surface,
					  cairo_image_surface_t **image_out,
					  void                  **image_extra)
{
    fprintf(stderr, "Getting source image\n");
    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
							abstract_surface);
    AutoLockView locker(surface->view);
    if (!locker) {
	_cairo_error(CAIRO_STATUS_NO_MEMORY);
	return CAIRO_STATUS_NO_MEMORY; /// XXX not exactly right, but what can we do?
    }


    surface->view->Sync();

    if (surface->bitmap) {
	*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
	if (!*image_out) {
	    _cairo_error(CAIRO_STATUS_NO_MEMORY);
	    return CAIRO_STATUS_NO_MEMORY;
	}

	*image_extra = NULL;
	return CAIRO_STATUS_SUCCESS;
    }

    BBitmap* bmp;
    if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK) {
	_cairo_error(CAIRO_STATUS_NO_MEMORY);
	return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE
    }

    *image_out = _cairo_beos_bitmap_to_surface(bmp);
    if (!*image_out) {
	delete bmp;
	_cairo_error(CAIRO_STATUS_NO_MEMORY);
	return CAIRO_STATUS_NO_MEMORY;
    }
    *image_extra = bmp;

    return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_beos_surface_composite (cairo_operator_t		op,
			       cairo_pattern_t	       *src,
			       cairo_pattern_t	       *mask,
			       void		       *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_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
							dst);
    AutoLockView locker(surface->view);
    if (!locker)
	return CAIRO_INT_STATUS_SUCCESS;

    drawing_mode mode;
    if (!_cairo_op_to_be_op(op, &mode))
	return CAIRO_INT_STATUS_UNSUPPORTED;

    // XXX Masks are not yet supported
    if (mask)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    // XXX should eventually support the others
    if (src->type != CAIRO_PATTERN_TYPE_SURFACE ||
	src->extend != CAIRO_EXTEND_NONE)
    {
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    // Can we maybe support other matrices as well? (scale? if the filter is right)
    int itx, ity;
    if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity))
	return CAIRO_INT_STATUS_UNSUPPORTED;

    BRect srcRect(src_x + itx,
		  src_y + ity,
		  src_x + itx + width - 1,
		  src_y + ity + height - 1);
    BRect dstRect(dst_x, dst_y, dst_x + width - 1, dst_y + height - 1);

    cairo_surface_t* src_surface = reinterpret_cast<cairo_surface_pattern_t*>(src)->
					surface;

    // Get a bitmap
    BBitmap* bmp = NULL;
    bool free_bmp = false;
    if (_cairo_surface_is_image(src_surface)) {
	cairo_image_surface_t* img_surface =
	    reinterpret_cast<cairo_image_surface_t*>(src_surface);

	bmp = _cairo_image_surface_to_bitmap(img_surface);
	free_bmp = true;
    } else if (src_surface->backend == surface->base.backend) {
	cairo_beos_surface_t *beos_surface =
	    reinterpret_cast<cairo_beos_surface_t*>(src_surface);
	if (beos_surface->bitmap) {
	    AutoLockView locker(beos_surface->view);
	    if (locker)
		beos_surface->view->Sync();
	    bmp = beos_surface->bitmap;
	} else {
	    _cairo_beos_view_to_bitmap(surface->view, &bmp);
	    free_bmp = true;
	}
    }

    if (!bmp)
	return CAIRO_INT_STATUS_UNSUPPORTED;

    // So, BeOS seems to screw up painting an opaque bitmap onto a
    // translucent one (it makes them partly transparent). Just return
    // unsupported.
    if (bmp->ColorSpace() == B_RGB32 && surface->bitmap &&
	surface->bitmap->ColorSpace() == B_RGBA32 &&
	(mode == B_OP_COPY || mode == B_OP_ALPHA))
    {
	if (free_bmp)
	    delete bmp;
	return CAIRO_INT_STATUS_UNSUPPORTED;
    }

    fprintf(stderr, "Composite\n");

    // Draw it on screen.
    surface->view->PushState();

	// If our image rect is only a subrect of the desired size, and we
	// aren't using B_OP_ALPHA, then we need to fill the rect first.
	if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) {
	    rgb_color black = { 0, 0, 0, 0 };

	    surface->view->SetDrawingMode(mode);
	    surface->view->SetHighColor(black);
	    surface->view->FillRect(dstRect);
	}

	if (mode == B_OP_ALPHA && bmp->ColorSpace() == B_RGB32) {
	    mode = B_OP_COPY;
	}
	surface->view->SetDrawingMode(mode);

	if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
	    surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
	else
	    surface->view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);

	surface->view->DrawBitmap(bmp, srcRect, dstRect);

    surface->view->PopState();

    if (free_bmp)
	delete bmp;

    return CAIRO_INT_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_beos_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_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
							abstract_surface);

    AutoLockView locker(surface->view);
    if (!locker) {
	*image_out = NULL;
	*image_extra = NULL;
	return CAIRO_STATUS_SUCCESS;
    }

    if (surface->bitmap) {
	surface->view->Sync();
	*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
	if (!*image_out)
	    return CAIRO_STATUS_NO_MEMORY;

	image_rect->x = 0;
	image_rect->y = 0;
	image_rect->width = (*image_out)->width;
	image_rect->height = (*image_out)->height;

	*image_extra = NULL;
	return CAIRO_STATUS_SUCCESS;
    }

    BRect b_interest_rect(_cairo_rect_to_brect(interest_rect));

    BRect rect;
    BBitmap* bitmap;
    ViewCopyStatus status = _cairo_beos_view_to_bitmap(surface->view, &bitmap,
	                                               &rect, &b_interest_rect);
    if (status == NOT_VISIBLE) {
	*image_out = NULL;
	*image_extra = NULL;
	return CAIRO_STATUS_SUCCESS;
    }
    if (status == ERROR)
	return CAIRO_STATUS_NO_MEMORY;

    *image_rect = _brect_to_cairo_rect(rect);

#if 0
    fprintf(stderr, "Requested: (cairo rects) (%ix%i) dim (%u, %u) returning (%ix%i) dim (%u, %u)\n",
	    interest_rect->x, interest_rect->y, interest_rect->width, interest_rect->height,
	    image_rect->x, image_rect->y, image_rect->width, image_rect->height);
#endif

    *image_out = _cairo_beos_bitmap_to_surface(bitmap);
    delete bitmap;
    if (!*image_out)
	return CAIRO_STATUS_NO_MEMORY;

    *image_extra = NULL;

    return CAIRO_STATUS_SUCCESS;
}