static cairo_int_status_t
_cairo_beos_surface_fill_rectangles (void			*abstract_surface,
				     cairo_operator_t		 op,
				     const cairo_color_t	*color,
				     cairo_rectangle_int16_t	*rects,
				     int			 num_rects)
{
    fprintf(stderr, "Drawing %i rectangles\n", num_rects);
    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
							abstract_surface);

    if (num_rects <= 0)
	return CAIRO_INT_STATUS_SUCCESS;

    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;

    rgb_color be_color = _cairo_color_to_be_color(color);

    if (mode == B_OP_ALPHA && be_color.alpha == 0xFF)
	mode = B_OP_COPY;

    // For CAIRO_OPERATOR_SOURCE, cairo expects us to use the premultiplied
    // color info. This is only relevant when drawing into an rgb24 buffer
    // (as for others, we can convert when asked for the image)
    if (mode == B_OP_COPY && be_color.alpha != 0xFF &&
	(!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32))
    {
	be_color.red = premultiply(be_color.red, be_color.alpha);
	be_color.green = premultiply(be_color.green, be_color.alpha);
	be_color.blue = premultiply(be_color.blue, be_color.alpha);
    }

    surface->view->PushState();

	surface->view->SetDrawingMode(mode);
	surface->view->SetHighColor(be_color);
	if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
	    surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
	else
	    surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);

	for (int i = 0; i < num_rects; ++i) {
	    _cairo_beos_surface_fill_rectangle(surface, &rects[i]);
	}

    surface->view->PopState();

    return CAIRO_INT_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;
}
예제 #3
0
static cairo_int_status_t
_cairo_beos_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_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;
    if (_cairo_surface_is_image(src_surface)) {
    	fprintf(stderr, "Composite\n");

	// Draw it on screen.
	cairo_image_surface_t* img_surface =
	    reinterpret_cast<cairo_image_surface_t*>(src_surface);

	BBitmap* bmp = _cairo_image_surface_to_bitmap(img_surface);
	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 && img_surface->format != CAIRO_FORMAT_ARGB32) {
		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();
	delete bmp;

	return CAIRO_INT_STATUS_SUCCESS;
    }

    return CAIRO_INT_STATUS_UNSUPPORTED;
}