/**
 * _cairo_beos_bitmap_to_surface:
 *
 * Returns an addrefed image surface for a BBitmap. The bitmap need not outlive
 * the surface.
 **/
static cairo_image_surface_t*
_cairo_beos_bitmap_to_surface (BBitmap* bitmap)
{
    color_space format = bitmap->ColorSpace();
    if (format != B_RGB32 && format != B_RGBA32) {
	BBitmap bmp(bitmap->Bounds(), B_RGB32, true);
	BView view(bitmap->Bounds(), "Cairo bitmap drawing view",
		   B_FOLLOW_ALL_SIDES, 0);
	bmp.AddChild(&view);

	view.LockLooper();

	view.DrawBitmap(bitmap, BPoint(0.0, 0.0));
	view.Sync();

	cairo_image_surface_t* imgsurf = _cairo_beos_bitmap_to_surface(&bmp);

	view.UnlockLooper();
	bmp.RemoveChild(&view);
	return imgsurf;
    }

    cairo_format_t cformat = format == B_RGB32 ? CAIRO_FORMAT_RGB24
						: CAIRO_FORMAT_ARGB32;

    BRect bounds(bitmap->Bounds());
    unsigned char* bits = reinterpret_cast<unsigned char*>(bitmap->Bits());
    int width = bounds.IntegerWidth() + 1;
    int height = bounds.IntegerHeight() + 1;
    unsigned char* premultiplied;
    if (cformat == CAIRO_FORMAT_ARGB32) {
       premultiplied = premultiply_rgba(bits, width, height,
					bitmap->BytesPerRow());
    } else {
	premultiplied = reinterpret_cast<unsigned char*>(
					_cairo_malloc_ab(bitmap->BytesPerRow(), height));
	if (premultiplied)
	    memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);
    }
    if (!premultiplied)
	return NULL;

    cairo_image_surface_t* surf = reinterpret_cast<cairo_image_surface_t*>
	(cairo_image_surface_create_for_data(premultiplied,
					     cformat,
					     width,
					     height,
					     bitmap->BytesPerRow()));
    if (surf->base.status)
	free(premultiplied);
    else
	_cairo_image_surface_assume_ownership_of_data(surf);
    return surf;
}
Ejemplo n.º 2
0
void
BitmapImage::PixmapComplete ()
{
	MoonPixbuf *pixbuf;
	
	SetProgress (1.0);

	if (!loader) {
		if (!moon_error)
			moon_error = new MoonError (MoonError::EXCEPTION, 4001, "no loader");
		goto failed;
	}

	loader->Close (moon_error == NULL ? &moon_error : NULL);

	if (moon_error)
		goto failed;

	if (!(pixbuf = loader->GetPixbuf ())) {
		moon_error = new MoonError (MoonError::EXCEPTION, 4001, "failed to create image data");
		goto failed;
	}
	
	SetPixelWidth (pixbuf->GetWidth ());
	SetPixelHeight (pixbuf->GetHeight ());
	
	// PixelFormat has been dropped and only Pbgra32 is supported
	// http://blogs.msdn.com/silverlight_sdk/archive/2009/07/01/breaking-changes-document-errata-silverlight-3.aspx
	// not clear if '3' channel is still supported (converted to 4) in SL3
	if (pixbuf->GetNumChannels () == 4) {
		SetBitmapData (premultiply_rgba (pixbuf), true);
	} else {
		SetBitmapData (expand_rgb_to_argb (pixbuf), true);
	}
	
	Invalidate ();
	
	delete loader;
	loader = NULL;
	
	if (HasHandlers (ImageOpenedEvent))
		Emit (ImageOpenedEvent, new RoutedEventArgs ());
	
	return;
	
failed:
	ImageErrorEventArgs *args = NULL;

	if (HasHandlers (ImageFailedEvent))
		args = new ImageErrorEventArgs (*moon_error);
	CleanupLoader ();
	if (args)
		Emit (ImageFailedEvent, args);
}