[cairo-commit] src/cairo-beos-surface.cpp
Christian Biesinger
biesi at kemper.freedesktop.org
Sun Mar 26 16:58:48 PST 2006
src/cairo-beos-surface.cpp | 204 +++++++++++++++++++++++++++++++++++----------
1 files changed, 159 insertions(+), 45 deletions(-)
New commits:
diff-tree 8fbd0d448dbdf8f556315366b64abe2468588ea6 (from 3259efed7690670754d7c1e76176ff26464111c3)
Author: Christian Biesinger <cbiesinger at web.de>
Date: Mon Mar 27 02:31:51 2006 +0200
Implement create_similar for BeOS
diff --git a/src/cairo-beos-surface.cpp b/src/cairo-beos-surface.cpp
index 6347ba7..dfb0217 100644
--- a/src/cairo-beos-surface.cpp
+++ b/src/cairo-beos-surface.cpp
@@ -70,6 +70,9 @@ struct cairo_beos_surface_t {
BBitmap* bitmap;
+ // If true, surface and view should be deleted when this surface is
+ // destroyed
+ bool owns_bitmap_view;
};
class AutoLockView {
@@ -92,6 +95,11 @@ class AutoLockView {
bool mOK;
};
+static cairo_surface_t *
+_cairo_beos_surface_create_internal (BView* view,
+ BBitmap* bmp,
+ bool owns_bitmap_view = false);
+
static BRect
_cairo_rect_to_brect (const cairo_rectangle_t* rect)
{
@@ -414,10 +422,76 @@ _cairo_op_to_be_op (cairo_operator_t cai
};
}
+static cairo_surface_t *
+_cairo_beos_surface_create_similar (void *abstract_surface,
+ cairo_content_t content,
+ int width,
+ int height)
+{
+ fprintf(stderr, "Creating similar\n");
+
+ cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+ abstract_surface);
+
+ if (width <= 0)
+ width = 1;
+ if (height <= 0)
+ height = 1;
+
+ BRect rect(0.0, 0.0, width - 1, height - 1);
+ BBitmap* bmp;
+ switch (content) {
+ case CAIRO_CONTENT_ALPHA:
+ // Can't support this natively
+ return _cairo_image_surface_create_with_content(content, width,
+ height);
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ bmp = new BBitmap(rect, B_RGBA32, true);
+ break;
+ case CAIRO_CONTENT_COLOR:
+ // Match the color depth
+ if (surface->bitmap) {
+ color_space space = surface->bitmap->ColorSpace();
+ // No alpha was requested -> make sure not to return
+ // a surface with alpha
+ if (space == B_RGBA32)
+ space = B_RGB32;
+ if (space == B_RGBA15)
+ space = B_RGB15;
+ bmp = new BBitmap(rect, space, true);
+ } else {
+ BScreen scr(surface->view->Window());
+ color_space space = B_RGB32;
+ if (scr.IsValid())
+ space = scr.ColorSpace();
+ bmp = new BBitmap(rect, space, true);
+ }
+ break;
+ default:
+ assert(0);
+ return NULL;
+
+ };
+ BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0);
+ bmp->AddChild(view);
+ return _cairo_beos_surface_create_internal(view, bmp, true);
+}
+
static cairo_status_t
_cairo_beos_surface_finish (void *abstract_surface)
{
- // Nothing to do
+ cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+ abstract_surface);
+ if (surface->owns_bitmap_view) {
+ if (surface->bitmap)
+ surface->bitmap->RemoveChild(surface->view);
+
+ delete surface->view;
+ delete surface->bitmap;
+
+ surface->view = NULL;
+ surface->bitmap = NULL;
+ }
return CAIRO_STATUS_SUCCESS;
}
@@ -549,13 +623,12 @@ _cairo_beos_surface_release_dest_image (
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
+
AutoLockView locker(surface->view);
if (!locker)
return;
-
BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image);
-
surface->view->PushState();
surface->view->SetDrawingMode(B_OP_COPY);
@@ -617,46 +690,78 @@ _cairo_beos_surface_composite (cairo_ope
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.
+ // 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);
- BBitmap* bmp = _cairo_image_surface_to_bitmap(img_surface);
- surface->view->PushState();
+ 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;
- // 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);
- }
+ // 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;
+ }
- if (mode == B_OP_ALPHA && img_surface->format != CAIRO_FORMAT_ARGB32) {
- mode = B_OP_COPY;
+ 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 (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);
+ if (mode == B_OP_ALPHA && bmp->ColorSpace() == B_RGB32) {
+ mode = B_OP_COPY;
+ }
+ surface->view->SetDrawingMode(mode);
- surface->view->DrawBitmap(bmp, srcRect, dstRect);
+ 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->PopState();
- delete bmp;
+ surface->view->DrawBitmap(bmp, srcRect, dstRect);
- return CAIRO_INT_STATUS_SUCCESS;
- }
+ surface->view->PopState();
- return CAIRO_INT_STATUS_UNSUPPORTED;
+ if (free_bmp)
+ delete bmp;
+
+ return CAIRO_INT_STATUS_SUCCESS;
}
@@ -778,7 +883,7 @@ _cairo_beos_surface_get_extents (void
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
CAIRO_SURFACE_TYPE_BEOS,
- NULL, /* create_similar */
+ _cairo_beos_surface_create_similar,
_cairo_beos_surface_finish,
_cairo_beos_surface_acquire_source_image,
_cairo_beos_surface_release_source_image,
@@ -807,6 +912,28 @@ static const struct _cairo_surface_backe
NULL /* show_glyphs */
};
+static cairo_surface_t *
+_cairo_beos_surface_create_internal (BView* view,
+ BBitmap* bmp,
+ bool owns_bitmap_view)
+{
+ // Must use malloc, because cairo code will use free() on the surface
+ cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
+ malloc(sizeof(cairo_beos_surface_t)));
+ if (surface == NULL) {
+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
+ }
+
+ _cairo_surface_init(&surface->base, &cairo_beos_surface_backend);
+
+ surface->view = view;
+ surface->bitmap = bmp;
+ surface->owns_bitmap_view = owns_bitmap_view;
+
+ return (cairo_surface_t *) surface;
+}
+
/**
* cairo_beos_surface_create:
* @view: The view to draw on
@@ -843,20 +970,7 @@ cairo_surface_t *
cairo_beos_surface_create_for_bitmap (BView* view,
BBitmap* bmp)
{
- // Must use malloc, because cairo code will use free() on the surface
- cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
- malloc(sizeof(cairo_beos_surface_t)));
- if (surface == NULL) {
- _cairo_error (CAIRO_STATUS_NO_MEMORY);
- return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
- }
-
- _cairo_surface_init(&surface->base, &cairo_beos_surface_backend);
-
- surface->view = view;
- surface->bitmap = bmp;
-
- return (cairo_surface_t *) surface;
+ return _cairo_beos_surface_create_internal(view, bmp);
}
// ---------------------------------------------------------------------------
More information about the cairo-commit
mailing list