[cairo] [patch] BeOS backend

Christian Biesinger cbiesinger at web.de
Mon Oct 10 15:36:27 PDT 2005


Hi,
attached is the first version of the BeOS backend. It passes the 
testsuite for ARGB32 bitmaps and almost passes it for RGB24 ones (and 
on-screen windows); the differences seem to be very small (color values 
differing by 1).
One test, ft-font-create-for-ft-face, crashes; but that's because of 
(the cross-platform bug) https://bugs.freedesktop.org/show_bug.cgi?id=4674.

There are two parts here; the cplusplus.diff one allows including 
cairoint.h in a C++ source file, while beos-backend.diff contains the 
actual backend.

I believe this to be ready for checkin. There's still work to do, 
especially implementing more functions in the backend, but this should 
be a good first step.

I developed and tested this on Zeta 1.0. The patch is made against trunk 
from today.


Some notes...
This backend doesn't have any depencies (except a BeOS system); however, 
the patch doesn't include a font backend, so freetype and fontconfig 
need to be installed. Implementing a native font backend might be hard, 
as beos doesn't support general affine transforms.

Building cairo as a shared library with this patch requires a libtool 
from CVS (http://lists.gnu.org/archive/html/libtool/2005-10/msg00012.html)

-biesi
-------------- next part --------------
Index: INSTALL
===================================================================
RCS file: /cvs/cairo/cairo/INSTALL,v
retrieving revision 1.4
diff -p -u -6 -r1.4 INSTALL
--- INSTALL	31 Aug 2005 20:52:19 -0000	1.4
+++ INSTALL	10 Oct 2005 22:02:24 -0000
@@ -63,12 +63,13 @@ More detailed build instructions
     --enable-ps
     --enable-pdf
     --enable-quartz
     --enable-atsui
     --enable-xcb
     --enable-glitz
+    --enable-beos
 
 	Some of cairo's backends are marked as experimental and will
 	not be built by default. If you would like to build and
 	experiment with these backends, you will need to pass one of
 	the above options to the configure script. You may need to
 	have certain libraries installed first as discussed in the
Index: README
===================================================================
RCS file: /cvs/cairo/cairo/README,v
retrieving revision 1.21
diff -p -u -6 -r1.21 README
--- README	24 Aug 2005 16:12:37 -0000	1.21
+++ README	10 Oct 2005 22:02:24 -0000
@@ -95,12 +95,17 @@ Surface backends:
 	XCB			http://xcb.freedesktop.org
 
 	xlib backend
 	------------
 	Xrender >= 0.6		http://freedesktop.org/Software/xlibs
 
+	beos backend
+	------------
+	No dependencies in itself other than an installed BeOS system, but cairo
+	requires a font backend. See the freetype dependency list.
+
 Font backends:
 
 	freetype font backend
 	---------------------
 	freetype >= 2.1.4	http://freetype.org
 	fontconfig		http://fontconfig.org
Index: configure.in
===================================================================
RCS file: /cvs/cairo/cairo/configure.in,v
retrieving revision 1.148
diff -p -u -6 -r1.148 configure.in
--- configure.in	8 Oct 2005 18:57:45 -0000	1.148
+++ configure.in	10 Oct 2005 22:02:24 -0000
@@ -187,12 +187,52 @@ AC_SUBST(WIN32_SURFACE_FEATURE)
 AM_CONDITIONAL(CAIRO_HAS_WIN32_FONT, test "x$use_win32" = "xyes")
 if test "x$use_win32" = "xyes"; then
   WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
 fi
 AC_SUBST(WIN32_FONT_FEATURE)
 
+
+dnl ===========================================================================
+
+
+AC_MSG_CHECKING([for BeOS/Zeta])
+case "$host" in
+  *-*-beos)
+    cairo_platform_beos=yes
+    ;;
+  *)
+    cairo_platform_beos=no
+    ;;
+esac
+AC_MSG_RESULT([$cairo_platform_beos])
+
+AC_ARG_ENABLE(beos,
+  [  --enable-beos            Disable cairo's BeOS/Zeta backend],
+  [use_beos=$enableval], [use_beos=no])
+
+if test "x$cairo_platform_beos" != "xyes" ; then
+  if test "x$use_beos" = "xyes"; then
+    AC_MSG_WARN([The BeOS backend requires a BeOS platform; disabling])
+    use_beos=no
+  fi
+fi
+
+if test "x$use_beos" = "xyes"; then
+  AC_PROG_CXX
+  dnl Add libbe and libzeta if available
+  AC_CHECK_LIB(be,main,CAIRO_LIBS="$CAIRO_LIBS -lbe")
+  AC_CHECK_LIB(zeta,main,CAIRO_LIBS="$CAIRO_LIBS -lzeta")
+fi
+
+AM_CONDITIONAL(CAIRO_HAS_BEOS_SURFACE, test "x$use_beos" = "xyes")
+if test "x$use_beos" = "xyes"; then
+  BEOS_SURFACE_FEATURE="#define CAIRO_HAS_BEOS_SURFACE 1"
+fi
+AC_SUBST(BEOS_SURFACE_FEATURE)
+
+
 dnl ===========================================================================
 
 AC_ARG_ENABLE(png,
   [  --disable-png           Disable cairo's PNG functions],
   [use_png=$enableval], [use_png=yes])
 
@@ -530,12 +570,13 @@ echo "  Xlib: $use_xlib"
 echo "  Quartz: $use_quartz"
 echo "  XCB: $use_xcb"
 echo "  Win32: $use_win32"
 echo "  PostScript: $use_ps"
 echo "  PDF: $use_pdf"
 echo "  glitz: $use_glitz"
+echo "  BeOS: $use_beos"
 echo ""
 echo "the following font backends:"
 echo "  FreeType: $use_freetype"
 echo "  Win32: $use_win32"
 echo "  ATSUI: $use_atsui"
 echo ""
Index: src/Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/src/Makefile.am,v
retrieving revision 1.66
diff -p -u -6 -r1.66 Makefile.am
--- src/Makefile.am	19 Sep 2005 21:14:03 -0000	1.66
+++ src/Makefile.am	10 Oct 2005 22:02:24 -0000
@@ -38,12 +38,18 @@ export_symbols = -export-symbols cairo.d
 cairo_def_dependency = cairo.def
 endif
 if CAIRO_HAS_WIN32_FONT
 libcairo_win32_sources += cairo-win32-font.c
 endif
 
+libcairo_beos_sources =
+if CAIRO_HAS_BEOS_SURFACE
+libcairo_beos_headers = cairo-beos.h
+libcairo_beos_sources += cairo-beos-surface.cpp
+endif
+
 if CAIRO_HAS_GLITZ_SURFACE
 libcairo_glitz_headers = cairo-glitz.h
 libcairo_glitz_sources = cairo-glitz-surface.c
 endif
 
 if CAIRO_HAS_ATSUI_FONT
@@ -80,12 +86,13 @@ cairoinclude_HEADERS =			\
 	$(libcairo_ft_headers)		\
 	$(libcairo_glitz_headers)	\
 	$(libcairo_pdf_headers)		\
 	$(libcairo_ps_headers)		\
 	$(libcairo_quartz_headers)	\
 	$(libcairo_win32_headers)	\
+	$(libcairo_beos_headers)	\
 	$(libcairo_xcb_headers)		\
 	$(libcairo_xlib_headers)
 
 lib_LTLIBRARIES = libcairo.la
 
 libcairo_la_SOURCES =				\
@@ -142,15 +149,19 @@ libcairo_la_SOURCES =				\
 	$(libcairo_png_sources)			\
 	$(libcairo_xlib_sources)		\
 	$(libcairo_quartz_sources)		\
 	$(libcairo_xcb_sources)			\
 	$(libcairo_glitz_sources)		\
 	$(libcairo_win32_sources)		\
+	$(libcairo_beos_sources)		\
 	cairoint.h
 
 libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined $(export_symbols)
+# this -Wno-multichar line is really just for the beos surface, because the
+# system headers trigger this warning.
+libcairo_la_CXXFLAGS = -Wno-multichar
 
 INCLUDES = -I$(srcdir) -I$(top_srcdir)/pixman/src $(CAIRO_CFLAGS)
 
 libcairo_la_LIBADD = $(top_builddir)/pixman/src/libpixman.la $(CAIRO_LIBS)
 
 libcairo_la_DEPENDENCIES = $(cairo_def_dependency) $(top_builddir)/pixman/src/libpixman.la
Index: src/cairo-beos-surface.cpp
===================================================================
RCS file: src/cairo-beos-surface.cpp
diff -N src/cairo-beos-surface.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/cairo-beos-surface.cpp	10 Oct 2005 22:02:24 -0000
@@ -0,0 +1,687 @@
+/* vim:set ts=8 sw=4 noet cin: */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2005 Christian Biesinger <cbiesinger at web.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Christian Biesinger
+ * <cbiesinger at web.de>
+ *
+ * Contributor(s):
+ */
+
+// This is a C++ file in order to use the C++ BeOS API
+
+#include <new>
+
+#include <Bitmap.h>
+#include <Region.h>
+#if 0
+#include <DirectWindow.h>
+#endif
+#include <Screen.h>
+#include <Window.h>
+#include <Locker.h>
+
+#include "cairoint.h"
+#include "cairo-private.h"
+#include "cairo-beos.h"
+
+#define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)(CAIRO_STATUS_SUCCESS)
+
+typedef struct cairo_beos_surface {
+    cairo_surface_t base;
+
+    BView* view;
+
+    /**
+     * A view is either attached to a bitmap, a window, or unattached.
+     * If it is attached to a window, we can copy data out of it using BScreen.
+     * If it is attached to a bitmap, we can read the bitmap data.
+     * If it is not attached, it doesn't draw anything, we need not bother.
+     *
+     * Since there doesn't seem to be a way to get the bitmap from a view if it
+     * is attached to one, we have to use a special surface creation function.
+     */
+
+    BBitmap* bitmap;
+
+
+} cairo_beos_surface_t;
+
+static BRect
+_cairo_rect_to_brect(const cairo_rectangle_t* rect)
+{
+    // A BRect is one pixel wider than you'd think
+    return BRect(rect->x, rect->y, rect->x + rect->width - 1,
+	    	 rect->y + rect->height - 1);
+}
+
+static cairo_rectangle_t
+_brect_to_cairo_rect(const BRect& rect)
+{
+    cairo_rectangle_t retval;
+    retval.x = int(rect.left + 0.5);
+    retval.y = int(rect.top + 0.5);
+    retval.width = rect.IntegerWidth() + 1;
+    retval.height = rect.IntegerHeight() + 1;
+    return retval;
+}
+
+static rgb_color
+_cairo_color_to_be_color(const cairo_color_t* color)
+{
+    // This factor ensures a uniform distribution of numbers
+    const float factor = 256 - 1e-5;
+    // Using doubles to have non-premultiplied colors
+    rgb_color be_color = { uint8(color->red * factor),
+			   uint8(color->green * factor),
+			   uint8(color->blue * factor),
+			   uint8(color->alpha * factor) };
+
+    return be_color;
+}
+
+enum ViewCopyStatus {
+    OK,
+    NOT_VISIBLE, // The view or the interest rect is not visible on screen
+    ERROR        // The view was visible, but the rect could not be copied. Probably OOM
+};
+
+/**
+ * Gets the contents of the view as a BBitmap*. Caller must delete the bitmap.
+ * @param bitmap[out] The resulting bitmap.
+ * @param[out] rect The rectangle that was copied, in the view's coordinate system
+ * @param interestRect If non-null, only this part of the view will be copied (view's coord system).
+ **/
+static ViewCopyStatus
+_cairo_beos_view_to_bitmap(BView* view, BBitmap** bitmap, BRect* rect = NULL, const BRect* interestRect = NULL)
+{
+    *bitmap = NULL;
+
+    BWindow* wnd = view->Window();
+    // If we have no window, can't do anything
+    if (!wnd)
+	return NOT_VISIBLE;
+
+    view->Sync();
+    wnd->Sync();
+
+#if 0
+    // Is it a direct window?
+    BDirectWindow* directWnd = dynamic_cast<BDirectWindow*>(wnd);
+    if (directWnd) {
+	// WRITEME
+    }
+#endif
+
+    // Is it visible? If so, we can copy the content off the screen
+    if (wnd->IsHidden())
+	return NOT_VISIBLE;
+
+    BRect rectToCopy(view->Bounds());
+    if (interestRect)
+	rectToCopy = rectToCopy & *interestRect;
+
+    if (!rectToCopy.IsValid())
+	return NOT_VISIBLE;
+
+    BScreen screen(wnd);
+    BRect screenRect(view->ConvertToScreen(rectToCopy));
+    screenRect = screenRect & screen.Frame();
+
+    if (!screen.IsValid())
+	return NOT_VISIBLE;
+
+    if (rect)
+	*rect = view->ConvertFromScreen(screenRect);
+
+    if (screen.GetBitmap(bitmap, false, &screenRect) == B_OK)
+	return OK;
+
+    return ERROR;
+}
+
+inline unsigned char
+unpremultiply(unsigned char color, unsigned char alpha)
+{
+    if (alpha == 0)
+	return 0;
+    // plus alpha/2 to round instead of truncate
+    return (color * 255 + alpha / 2) / alpha;
+}
+
+inline unsigned char
+premultiply(unsigned char color, unsigned char alpha)
+{
+    // + 127 to round, instead of truncate
+    return (color * alpha + 127) / 255;
+}
+
+/**
+ * Takes an input in ABGR premultiplied image data and unmultiplies it.
+ * The result is stored in retdata.
+ */
+static void
+unpremultiply_rgba(unsigned char* data, int width, int height, int stride,
+		   unsigned char* retdata)
+{
+    unsigned char* end = data + stride * height;
+    for (unsigned char* in = data, *out = retdata;
+	 in < end;
+	 in += stride, out += stride)
+    {
+	for (int i = 0; i < width; ++i) {
+	    // XXX for a big-endian platform this'd have to change
+	    int idx = 4 * i;
+	    unsigned char alpha = in[idx + 3];
+	    out[idx + 0] = unpremultiply(in[idx + 0], alpha); // B
+	    out[idx + 1] = unpremultiply(in[idx + 1], alpha); // G
+	    out[idx + 2] = unpremultiply(in[idx + 2], alpha); // R
+	    out[idx + 3] = in[idx + 3]; // Alpha
+	}
+    }
+}
+
+/**
+ * Takes an input in ABGR non-premultiplied image data and premultiplies it.
+ * The returned data must be freed with free().
+ */
+static unsigned char*
+premultiply_rgba(unsigned char* data, int width, int height, int stride)
+{
+    unsigned char* retdata = reinterpret_cast<unsigned char*>(malloc(stride * height));
+    if (!retdata)
+	return NULL;
+
+    unsigned char* end = data + stride * height;
+    for (unsigned char* in = data, *out = retdata;
+	 in < end;
+	 in += stride, out += stride)
+    {
+	for (int i = 0; i < width; ++i) {
+	    // XXX for a big-endian platform this'd have to change
+	    int idx = 4 * i;
+	    unsigned char alpha = in[idx + 3];
+	    out[idx + 0] = premultiply(in[idx + 0], alpha); // B
+	    out[idx + 1] = premultiply(in[idx + 1], alpha); // G
+	    out[idx + 2] = premultiply(in[idx + 2], alpha); // R
+	    out[idx + 3] = in[idx + 3]; // Alpha
+	}
+    }
+    return retdata;
+}
+
+/**
+ * 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*>(
+					malloc(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;
+}
+
+/**
+ * Converts an image surface to a BBitmap. The return value must be freed with
+ * delete.
+ */
+static BBitmap*
+_cairo_image_surface_to_bitmap(cairo_image_surface_t* surface)
+{
+    BRect size(0.0, 0.0, surface->width - 1, surface->height - 1);
+    switch (surface->format) {
+	case CAIRO_FORMAT_ARGB32: {
+	    BBitmap* data = new BBitmap(size, B_RGBA32);
+	    unpremultiply_rgba(surface->data,
+			       surface->width,
+			       surface->height,
+			       surface->stride,
+			       reinterpret_cast<unsigned char*>(data->Bits()));
+	    return data;
+        }
+	case CAIRO_FORMAT_RGB24: {
+	    BBitmap* data = new BBitmap(size, B_RGB32);
+	    memcpy(data->Bits(), surface->data, surface->height * surface->stride);
+	    return data;
+	}
+	default:
+	    return NULL;
+    }
+}
+
+/**
+ * Converts a cairo drawing operator to a beos drawing_mode. Returns true if
+ * the operator could be converted, false otherwise.
+ */
+static bool
+_cairo_op_to_be_op(cairo_operator_t cairo_op, drawing_mode* beos_op)
+{
+    switch (cairo_op) {
+
+	case CAIRO_OPERATOR_SOURCE:
+	    *beos_op = B_OP_COPY;
+	    return true;
+	case CAIRO_OPERATOR_OVER:
+	    *beos_op = B_OP_ALPHA;
+	    return true;
+
+	case CAIRO_OPERATOR_ADD:
+	    *beos_op = B_OP_ADD;
+	    return true;
+
+	case CAIRO_OPERATOR_CLEAR:
+	    // Does not map to B_OP_ERASE - it replaces the dest with the low
+	    // color, instead of transparency; could be done by setting low
+	    // color appropriately.
+	case CAIRO_OPERATOR_IN:
+	case CAIRO_OPERATOR_OUT:
+	case CAIRO_OPERATOR_ATOP:
+
+	case CAIRO_OPERATOR_DEST:
+	case CAIRO_OPERATOR_DEST_OVER:
+	case CAIRO_OPERATOR_DEST_IN:
+	case CAIRO_OPERATOR_DEST_OUT:
+	case CAIRO_OPERATOR_DEST_ATOP:
+
+	case CAIRO_OPERATOR_XOR:
+	case CAIRO_OPERATOR_SATURATE:
+
+	default:
+	    return false;
+    };
+}
+
+static cairo_status_t
+_cairo_beos_surface_finish(void *abstract_surface)
+{
+    // Nothing to do
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+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);
+    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 void
+_cairo_beos_surface_release_source_image(void *abstract_surface,
+					 cairo_image_surface_t *image,
+					 void *image_extra)
+{
+    cairo_surface_destroy (&image->base);
+
+    BBitmap* bmp = static_cast<BBitmap*>(image_extra);
+    delete bmp;
+}
+
+
+
+static cairo_status_t
+_cairo_beos_surface_acquire_dest_image(void *abstract_surface,
+                                         cairo_rectangle_t * interest_rect,
+                                         cairo_image_surface_t ** image_out,
+                                         cairo_rectangle_t * image_rect,
+                                         void **image_extra)
+{
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+
+    if (surface->bitmap) {
+	surface->view->Sync();
+	*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
+	if (!*image_out) {
+	    _cairo_error(CAIRO_STATUS_NO_MEMORY);
+	    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) {
+	_cairo_error(CAIRO_STATUS_NO_MEMORY);
+	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) {
+	_cairo_error(CAIRO_STATUS_NO_MEMORY);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
+    *image_extra = NULL;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+
+static void
+_cairo_beos_surface_release_dest_image(void *abstract_surface,
+                                         cairo_rectangle_t *
+                                         intersect_rect,
+                                         cairo_image_surface_t * image,
+                                         cairo_rectangle_t * image_rect,
+                                         void *image_extra)
+{
+    fprintf(stderr, "Fallback drawing\n");
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+
+    BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image);
+
+    surface->view->PushState();
+
+	surface->view->SetDrawingMode(B_OP_COPY);
+	BRect rect(_cairo_rect_to_brect(image_rect));
+
+	surface->view->DrawBitmap(bitmap_to_draw, rect);
+
+    surface->view->PopState();
+
+    delete bitmap_to_draw;
+    cairo_surface_destroy(&image->base);
+}
+
+static void
+_cairo_beos_fill_rectangle(cairo_beos_surface_t* surface,
+		      cairo_rectangle_t* rect)
+{
+    BRect brect(_cairo_rect_to_brect(rect));
+    surface->view->FillRect(brect);
+}
+
+static cairo_int_status_t
+_cairo_beos_fill_rectangles(void *abstract_surface,
+			    cairo_operator_t op,
+			    const cairo_color_t *color,
+			    cairo_rectangle_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;
+
+    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;
+
+    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_fill_rectangle(surface, &rects[i]);
+	}
+
+    surface->view->PopState();
+
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
+
+
+static cairo_int_status_t
+_cairo_beos_surface_set_clip_region(void *abstract_surface,
+                                      pixman_region16_t * region)
+{
+    fprintf(stderr, "Setting clip region\n");
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+    if (region == NULL) {
+	// No clipping
+	surface->view->ConstrainClippingRegion(NULL);
+	return CAIRO_INT_STATUS_SUCCESS;
+    }
+
+    int count = pixman_region_num_rects(region);
+    pixman_box16_t* rects = pixman_region_rects(region);
+    BRegion bregion;
+    for (int i = 0; i < count; ++i) {
+	// Have to substract one, because for pixman, the second coordinate
+	// lies outside the rectangle.
+	bregion.Include(BRect(rects[i].x1, rects[i].y1, rects[i].x2 - 1, rects[i].y2  - 1));
+    }
+    surface->view->ConstrainClippingRegion(&bregion);
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_beos_surface_get_extents (void *abstract_surface,
+				   cairo_rectangle_t * rectangle)
+{
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+
+    BRect size = surface->view->Bounds();
+
+    *rectangle = _brect_to_cairo_rect(size);
+
+    // Make sure to have our upperleft edge as (0,0)
+    rectangle->x = 0;
+    rectangle->y = 0;
+
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
+static const struct _cairo_surface_backend cairo_beos_surface_backend = {
+    NULL, /* create_similar */ // should implement
+    _cairo_beos_surface_finish,
+    _cairo_beos_surface_acquire_source_image,
+    _cairo_beos_surface_release_source_image,
+    _cairo_beos_surface_acquire_dest_image,
+    _cairo_beos_surface_release_dest_image,
+    NULL, /* clone_similar */ // should implement
+    NULL, /* composite */ // should implement
+    _cairo_beos_fill_rectangles,
+    NULL, /* composite_trapezoids */ // should implement (antialiasing?)
+    NULL, /* copy_page */
+    NULL, /* show_page */
+    _cairo_beos_surface_set_clip_region,
+    NULL, /* intersect_clip_path */ // should implement
+    _cairo_beos_surface_get_extents,
+    NULL,  /* show_glyphs */
+    NULL, /* fill_path */ // should implement (antialiasing?)
+    NULL, /* get_font_options */
+    NULL, /* flush */
+    NULL /* mark_dirty_rectangle */
+};
+
+cairo_surface_t *
+cairo_beos_surface_create(BView* view)
+{
+    return cairo_beos_surface_create_for_bitmap(view, NULL);
+}
+
+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;
+}
+
+// ---------------------------------------------------------------------------
+// Cairo uses locks without explicit initialization. To support that, we
+// provide a class here which manages the locks and is in global scope, so the
+// compiler will instantiate it on library load and destroy it on library
+// unload.
+
+class BeLocks {
+    public:
+	BLocker cairo_toy_font_face_hash_table_mutex;
+	BLocker cairo_scaled_font_map_mutex;
+	BLocker cairo_ft_unscaled_font_map_mutex;
+};
+
+static BeLocks locks;
+
+void* cairo_toy_font_face_hash_table_mutex = &locks.cairo_toy_font_face_hash_table_mutex;
+void* cairo_scaled_font_map_mutex = &locks.cairo_scaled_font_map_mutex;
+void* cairo_ft_unscaled_font_map_mutex = &locks.cairo_ft_unscaled_font_map_mutex;
+
+void _cairo_beos_lock(void* locker) {
+    BLocker* bLocker = reinterpret_cast<BLocker*>(locker);
+    bLocker->Lock();
+}
+
+void _cairo_beos_unlock(void* locker) {
+    BLocker* bLocker = reinterpret_cast<BLocker*>(locker);
+    bLocker->Unlock();
+}
+
Index: src/cairo-beos.h
===================================================================
RCS file: src/cairo-beos.h
diff -N src/cairo-beos.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/cairo-beos.h	10 Oct 2005 22:02:24 -0000
@@ -0,0 +1,77 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2005 Christian Biesinger <cbiesinger at web.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Christian Biesinger
+ * <cbiesinger at web.de>
+ *
+ * Contributor(s):
+ */
+
+#ifndef CAIRO_BEOS_H
+#define CAIRO_BEOS_H
+
+#include <cairo.h>
+
+#if CAIRO_HAS_BEOS_SURFACE
+
+#include <View.h>
+
+CAIRO_BEGIN_DECLS
+
+/**
+ * Creates a Cairo surface that draws onto a BeOS BView.
+ * The caller must ensure that the view does not get deleted before the surface.
+ */
+cairo_public cairo_surface_t *
+cairo_beos_surface_create (BView*		view);
+
+/**
+ * Creates a Cairo surface that draws onto a BeOS BView which is attached to a
+ * BBitmap.
+ * The caller must ensure that the view and the bitmap do not get deleted
+ * before the surface.
+ *
+ * For views that draw to a bitmap (as opposed to a screen), use this function
+ * rather than cairo_beos_surface_create. Not using this function WILL lead to
+ * incorrect behaviour.
+ *
+ * For now, only views that draw to the entire area of bmp are supported.
+ * The view must already be attached to the bitmap.
+ */
+cairo_public cairo_surface_t *
+cairo_beos_surface_create_for_bitmap (BView* view, BBitmap* bmp);
+
+CAIRO_END_DECLS
+
+#else  /* CAIRO_HAS_BEOS_SURFACE */
+# error Cairo was not compiled with support for the beos backend
+#endif /* CAIRO_HAS_BEOS_SURFACE */
+
+#endif /* CAIRO_BEOS_H */
+
Index: src/cairo-features.h.in
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-features.h.in,v
retrieving revision 1.22
diff -p -u -6 -r1.22 cairo-features.h.in
--- src/cairo-features.h.in	7 Sep 2005 23:31:22 -0000	1.22
+++ src/cairo-features.h.in	10 Oct 2005 22:02:24 -0000
@@ -64,12 +64,14 @@
 @QUARTZ_SURFACE_FEATURE@
 
 @XCB_SURFACE_FEATURE@
 
 @WIN32_SURFACE_FEATURE@
 
+ at BEOS_SURFACE_FEATURE@
+
 @GLITZ_SURFACE_FEATURE@
 
 @FT_FONT_FEATURE@
 
 @WIN32_FONT_FEATURE@
 
Index: src/cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.214
diff -p -u -6 -r1.214 cairoint.h
--- src/cairoint.h	10 Oct 2005 19:45:15 -0000	1.214
+++ src/cairoint.h	10 Oct 2005 22:02:24 -0000
@@ -145,12 +147,23 @@
 # define CAIRO_MUTEX_DECLARE(name) extern CRITICAL_SECTION name; 
 # define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern LPCRITICAL_SECTION name;
 # define CAIRO_MUTEX_LOCK(name) EnterCriticalSection (&name)
 # define CAIRO_MUTEX_UNLOCK(name) LeaveCriticalSection (&name)
 #endif
 
+#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_BEOS_SURFACE
+cairo_private void _cairo_beos_lock(void*);
+cairo_private void _cairo_beos_unlock(void*);
+  /* the real initialization takes place in a global constructor */
+# define CAIRO_MUTEX_DECLARE(name) extern void* name; 
+# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern void* name;
+# define CAIRO_MUTEX_LOCK(name) _cairo_beos_lock (&name)
+# define CAIRO_MUTEX_UNLOCK(name) _cairo_beos_unlock (&name)
+#endif
+
+
 #ifndef CAIRO_MUTEX_DECLARE
 # error "No mutex declarations. Cairo will not work with multiple threads." \
 	"(Remove this #error directive to acknowledge & accept this limitation)."
 # define CAIRO_MUTEX_DECLARE(name)
 # define CAIRO_MUTEX_DECLARE_GLOBAL(name)
 # define CAIRO_MUTEX_LOCK(name)
Index: test/.cvsignore
===================================================================
RCS file: /cvs/cairo/cairo/test/.cvsignore,v
retrieving revision 1.56
diff -p -u -6 -r1.56 .cvsignore
--- test/.cvsignore	9 Oct 2005 21:51:55 -0000	1.56
+++ test/.cvsignore	10 Oct 2005 22:02:24 -0000
@@ -79,10 +79,13 @@ xlib-surface
 *-xcb-out.png
 *-xcb-argb32-out.png
 *-xcb-rgb24-out.png
 *-xlib-out.png
 *-xlib-argb32-out.png
 *-xlib-rgb24-out.png
+*-beos-rgb24-out.png
+*-beos_bitmap-rgb24-out.png
+*-beos_bitmap-argb32-out.png
 *-diff.png
 *.la
 *.lo
 *.log
Index: test/Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/test/Makefile.am,v
retrieving revision 1.97
diff -p -u -6 -r1.97 Makefile.am
--- test/Makefile.am	9 Oct 2005 21:51:55 -0000	1.97
+++ test/Makefile.am	10 Oct 2005 22:02:24 -0000
@@ -239,12 +239,18 @@ read-png.c	\
 read-png.h	\
 write-png.c	\
 write-png.h	\
 xmalloc.c	\
 xmalloc.h
 
+if CAIRO_HAS_BEOS_SURFACE
+libcairotest_la_SOURCES += cairo-test-beos.cpp cairo-test-beos.h
+# BeOS system headers trigger this warning
+libcairotest_la_CXXFLAGS = -Wno-multichar
+endif
+
 LDADDS = libcairotest.la $(top_builddir)/src/libcairo.la
 
 if HAVE_PTHREAD
 LDADDS += -lpthread
 endif
 
Index: test/cairo-test-beos.cpp
===================================================================
RCS file: test/cairo-test-beos.cpp
diff -N test/cairo-test-beos.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test/cairo-test-beos.cpp	10 Oct 2005 22:02:24 -0000
@@ -0,0 +1,239 @@
+/* vim:set ts=8 sw=4 noet cin: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Takashi Toyoshima <toyoshim at be-in.org>
+ *   Fredrik Holmqvist <thesuckiestemail at yahoo.se>
+ *   Christian Biesinger <cbiesinger at web.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Part of this code was originally part of
+// xpfe/bootstrap/nsNativeAppSupportBeOS.cpp in the Mozilla source code.
+
+#include <Application.h>
+#include <Window.h>
+#include <View.h>
+#include <Bitmap.h>
+
+extern "C" {
+#include "cairo-test.h"
+}
+
+#include "cairo-test-beos.h"
+#include "cairo-beos.h"
+
+class CairoTestWindow : public BWindow
+{
+public:
+    CairoTestWindow(BRect frame, const char* title);
+    virtual ~CairoTestWindow();
+    BView* View() const { return mView; }
+private:
+    BView* mView;
+};
+
+CairoTestWindow::CairoTestWindow(BRect frame, const char* title)
+    : BWindow(frame, title, B_TITLED_WINDOW,
+	      B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
+{
+    mView = new BView(frame, "CairoWindowTestView", B_FOLLOW_ALL_SIDES, 0);
+    AddChild(mView);
+    Show();
+}
+
+CairoTestWindow::~CairoTestWindow()
+{
+    RemoveChild(mView);
+    delete mView;
+}
+
+
+class nsBeOSApp : public BApplication
+{
+public:
+    nsBeOSApp(sem_id sem) : BApplication(GetAppSig()), init(sem)
+    {}
+
+    void ReadyToRun()
+    {
+        release_sem(init);
+    }
+
+    static int32 Main(void *args)
+    {
+        nsBeOSApp *app = new nsBeOSApp( (sem_id)args );
+        if(app == NULL)
+            return B_ERROR;
+        return app->Run();
+    }
+
+private:
+
+    const char *GetAppSig()
+    {
+        return "application/x-vnd.cairo-test-app";
+    }
+
+    sem_id init;
+}; //class nsBeOSApp
+
+class AppRunner
+{
+    public:
+	AppRunner();
+	~AppRunner();
+};
+
+AppRunner::AppRunner()
+{
+    if (be_app)
+	return;
+
+    sem_id initsem = create_sem(0, "Cairo BApplication init");
+    if (initsem < B_OK) {
+	cairo_test_log("Error creating BeOS initialization semaphore\n");
+        return;
+    }
+
+    thread_id tid = spawn_thread(nsBeOSApp::Main, "Cairo/BeOS test", B_NORMAL_PRIORITY, (void *)initsem);
+    if (tid < B_OK || B_OK != resume_thread(tid)) {
+	cairo_test_log("Error spawning thread\n");
+	return;
+    }
+
+    if (B_OK != acquire_sem(initsem)) {
+	cairo_test_log("Error acquiring semaphore\n");
+	return;
+    }
+
+    delete_sem(initsem);
+    return;
+}
+
+AppRunner::~AppRunner()
+{
+    if (be_app) {
+	if (be_app->Lock())
+	    be_app->Quit();
+	delete be_app;
+	be_app = NULL;
+    }
+}
+
+// Make sure that the BApplication is initialized
+static AppRunner sAppRunner;
+
+struct beos_test_closure
+{
+    BView* view;
+    BBitmap* bitmap;
+    BWindow* window;
+};
+
+// Test a real window
+cairo_surface_t *
+create_beos_surface (cairo_test_t* test, cairo_format_t format, void **closure)
+{
+    float right = test->width ? test->width - 1 : 0;
+    float bottom = test->height ? test->height - 1 : 0;
+    BRect rect(0.0, 0.0, right, bottom);
+    CairoTestWindow* wnd = new CairoTestWindow(rect, test->name);
+    if (!wnd->View()->LockLooper()) {
+	cairo_test_log("Error locking looper\n");
+	return NULL;
+    }
+
+    beos_test_closure* bclosure = new beos_test_closure;
+    bclosure->view = wnd->View();
+    bclosure->bitmap = NULL;
+    bclosure->window = wnd;
+
+    *closure = bclosure;
+
+    return cairo_beos_surface_create(wnd->View());
+}
+
+void
+cleanup_beos (void* closure)
+{
+    beos_test_closure* bclosure = reinterpret_cast<beos_test_closure*>(closure);
+
+    bclosure->window->Quit();
+
+    delete bclosure;
+}
+
+// Test a bitmap
+cairo_surface_t *
+create_beos_bitmap_surface (cairo_test_t* test, cairo_format_t format,
+	                    void **closure)
+{
+    BRect rect(0.0, 0.0, test->width - 1, test->height - 1);
+    color_space beosformat = (format == CAIRO_FORMAT_RGB24) ? B_RGB32
+							    : B_RGBA32;
+    BBitmap* bmp = new BBitmap(rect, beosformat, true);
+    BView* view = new BView(rect, "Cairo test view", B_FOLLOW_ALL_SIDES, 0);
+    bmp->AddChild(view);
+
+    if (!view->LockLooper()) {
+	cairo_test_log("Error locking looper\n");
+	return NULL;
+    }
+
+    beos_test_closure* bclosure = new beos_test_closure;
+    bclosure->view = view;
+    bclosure->bitmap = bmp;
+    bclosure->window = NULL;
+    *closure = bclosure;
+
+    return cairo_beos_surface_create_for_bitmap(view, bmp);
+}
+
+void
+cleanup_beos_bitmap (void* closure)
+{
+    beos_test_closure* bclosure = reinterpret_cast<beos_test_closure*>(closure);
+
+    bclosure->view->UnlockLooper();
+
+    bclosure->bitmap->RemoveChild(bclosure->view);
+
+
+    delete bclosure->view;
+    delete bclosure->bitmap;
+
+    delete bclosure;
+}
+
+
Index: test/cairo-test-beos.h
===================================================================
RCS file: test/cairo-test-beos.h
diff -N test/cairo-test-beos.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test/cairo-test-beos.h	10 Oct 2005 22:02:24 -0000
@@ -0,0 +1,26 @@
+#ifndef CAIRO_TEST_BEOS_H_
+#define CAIRO_TEST_BEOS_H_
+
+/* Two functions: One for a real window, one for a bitmap */
+
+#include <cairo.h>
+
+CAIRO_BEGIN_DECLS
+
+extern cairo_surface_t *
+create_beos_surface (cairo_test_t* test, cairo_format_t format,
+                     void **closure);
+
+extern void
+cleanup_beos (void* closure);
+
+extern cairo_surface_t *
+create_beos_bitmap_surface (cairo_test_t* test, cairo_format_t format,
+                            void **closure);
+
+extern void
+cleanup_beos_bitmap (void* closure);
+
+CAIRO_END_DECLS
+
+#endif
Index: test/cairo-test.c
===================================================================
RCS file: /cvs/cairo/cairo/test/cairo-test.c,v
retrieving revision 1.61
diff -p -u -6 -r1.61 cairo-test.c
--- test/cairo-test.c	8 Oct 2005 18:58:20 -0000	1.61
+++ test/cairo-test.c	10 Oct 2005 22:02:24 -0000
@@ -470,12 +470,17 @@ cleanup_xlib (void *closure)
     XFreePixmap (xtc->dpy, xtc->pixmap);
     XCloseDisplay (xtc->dpy);
     free (xtc);
 }
 #endif
 
+#if CAIRO_HAS_BEOS_SURFACE
+/* BeOS test functions are external as they need to be C++ */
+#include "cairo-test-beos.h"
+#endif
+
 #if CAIRO_HAS_PS_SURFACE
 #include "cairo-ps.h"
 
 cairo_user_data_key_t	ps_closure_key;
 
 typedef struct _ps_target_closure
@@ -685,12 +690,20 @@ cairo_test_expecting (cairo_test_t *test
 		create_ps_surface, ps_surface_write_to_png, cleanup_ps },
 #endif
 #if 0 && CAIRO_HAS_PDF_SURFACE
 	    { "pdf", CAIRO_FORMAT_RGB24, 
 		create_pdf_surface, pdf_surface_write_to_png, cleanup_pdf },
 #endif
+#if CAIRO_HAS_BEOS_SURFACE
+	    { "beos", CAIRO_FORMAT_RGB24,
+		create_beos_surface, cairo_surface_write_to_png, cleanup_beos},
+	    { "beos_bitmap", CAIRO_FORMAT_RGB24,
+		create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
+	    { "beos_bitmap", CAIRO_FORMAT_ARGB32,
+		create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
+#endif
 	};
 
     cairo_test_init (test->name);
 
     /* The intended logic here is that we return overall SUCCESS
      * iff. there is at least one tested backend and that all tested
-------------- next part --------------
Index: .cvsignore
===================================================================
RCS file: /cvs/cairo/cairo/.cvsignore,v
retrieving revision 1.6
diff -p -u -6 -r1.6 .cvsignore
--- .cvsignore	27 Oct 2004 20:13:39 -0000	1.6
+++ .cvsignore	10 Oct 2005 21:58:12 -0000
@@ -14,7 +14,12 @@ configure
 libtool
 ltmain.sh
 releases
 stamp-h
 stamp-h1
 stamp-h.in
+compile
+depcomp
+install-sh
+missing
+mkinstalldirs
 
Index: src/cairo-clip-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-clip-private.h,v
retrieving revision 1.3
diff -p -u -6 -r1.3 cairo-clip-private.h
--- src/cairo-clip-private.h	9 Aug 2005 01:35:22 -0000	1.3
+++ src/cairo-clip-private.h	10 Oct 2005 21:58:12 -0000
@@ -35,18 +35,12 @@
 
 #ifndef CAIRO_CLIP_PRIVATE_H
 #define CAIRO_CLIP_PRIVATE_H
 
 #include "cairo-path-fixed-private.h"
 
-enum _cairo_clip_mode {
-    CAIRO_CLIP_MODE_PATH,
-    CAIRO_CLIP_MODE_REGION,
-    CAIRO_CLIP_MODE_MASK
-};
-
 struct _cairo_clip_path {
     unsigned int	ref_count;
     cairo_path_fixed_t	path;
     cairo_fill_rule_t	fill_rule;
     double		tolerance;
     cairo_antialias_t	antialias;
@@ -111,13 +105,13 @@ _cairo_clip_intersect_to_rectangle (cair
 cairo_private cairo_status_t
 _cairo_clip_intersect_to_region (cairo_clip_t      *clip,
 				 pixman_region16_t *region);
 
 cairo_private cairo_status_t
 _cairo_clip_combine_to_surface (cairo_clip_t            *clip,
-				cairo_operator_t         operator,
+				cairo_operator_t         op,
 				cairo_surface_t         *dst,
 				int                      dst_x,
 				int                      dst_y,
 				const cairo_rectangle_t *extents);
 
 #endif /* CAIRO_CLIP_PRIVATE_H */
Index: src/cairo-gstate-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate-private.h,v
retrieving revision 1.17
diff -p -u -6 -r1.17 cairo-gstate-private.h
--- src/cairo-gstate-private.h	24 Aug 2005 08:39:56 -0000	1.17
+++ src/cairo-gstate-private.h	10 Oct 2005 21:58:12 -0000
@@ -36,13 +36,13 @@
 #ifndef CAIRO_GSTATE_PRIVATE_H
 #define CAIRO_GSTATE_PRIVATE_H
 
 #include "cairo-clip-private.h"
 
 struct _cairo_gstate {
-    cairo_operator_t operator;
+    cairo_operator_t op;
     
     double tolerance;
     cairo_antialias_t antialias;
 
     /* stroke style */
     double line_width;
Index: src/cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.171
diff -p -u -6 -r1.171 cairo-gstate.c
--- src/cairo-gstate.c	10 Oct 2005 16:36:39 -0000	1.171
+++ src/cairo-gstate.c	10 Oct 2005 21:58:13 -0000
@@ -86,13 +86,13 @@ _cairo_gstate_create (cairo_surface_t *t
 }
 
 static cairo_status_t
 _cairo_gstate_init (cairo_gstate_t  *gstate,
 		    cairo_surface_t *target)
 {
-    gstate->operator = CAIRO_GSTATE_OPERATOR_DEFAULT;
+    gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
 
     gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT;
     gstate->antialias = CAIRO_ANTIALIAS_DEFAULT;
 
     gstate->line_width = CAIRO_GSTATE_LINE_WIDTH_DEFAULT;
     gstate->line_cap = CAIRO_GSTATE_LINE_CAP_DEFAULT;
@@ -287,13 +287,13 @@ _cairo_gstate_end_group (cairo_gstate_t 
 
     _cairo_surface_set_solid_color (&mask, &mask_color);
 
     * XXX: This could be made much more efficient by using
        _cairo_surface_get_damaged_width/Height if cairo_surface_t actually kept
        track of such informaton. *
-    _cairo_surface_composite (gstate->operator,
+    _cairo_surface_composite (gstate->op,
 			      gstate->target,
 			      mask,
 			      gstate->parent_surface,
 			      0, 0,
 			      0, 0,
 			      0, 0,
@@ -343,21 +343,21 @@ _cairo_gstate_get_source (cairo_gstate_t
     return gstate->source;
 }
 
 cairo_status_t
 _cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t operator)
 {
-    gstate->operator = operator;
+    gstate->op = operator;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 cairo_operator_t
 _cairo_gstate_get_operator (cairo_gstate_t *gstate)
 {
-    return gstate->operator;
+    return gstate->op;
 }
 
 cairo_status_t
 _cairo_gstate_set_tolerance (cairo_gstate_t *gstate, double tolerance)
 {
     gstate->tolerance = tolerance;
@@ -1171,13 +1171,13 @@ _cairo_gstate_mask (cairo_gstate_t  *gst
 
     _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
     _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
     
     _get_mask_extents (gstate, &mask_pattern.base, &extents);
     
-    status = _cairo_gstate_clip_and_composite (&gstate->clip, gstate->operator,
+    status = _cairo_gstate_clip_and_composite (&gstate->clip, gstate->op,
 					       &source_pattern.base, 
 					       _cairo_gstate_mask_draw_func, &mask_pattern.base,
 					       gstate->target,
 					       &extents);
 
     _cairo_pattern_fini (&source_pattern.base);
@@ -1539,13 +1539,13 @@ _cairo_gstate_clip_and_composite_trapezo
   cairo_pattern_union_t pattern;
   cairo_status_t status;
   
   _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
   
   status = _cairo_surface_clip_and_composite_trapezoids (&pattern.base,
-							 gstate->operator,
+							 gstate->op,
 							 gstate->target,
 							 traps,
 							 &gstate->clip,
 							 gstate->antialias);
 
   _cairo_pattern_fini (&pattern.base);
@@ -1566,13 +1566,13 @@ _cairo_gstate_fill (cairo_gstate_t *gsta
     status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
     if (status)
 	return status;
   
     _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
 
-    status = _cairo_surface_fill_path (gstate->operator,
+    status = _cairo_surface_fill_path (gstate->op,
 				       &pattern.base,
 				       gstate->target,
 				       path,
 				       gstate->fill_rule,
 				       gstate->tolerance);
     
@@ -2100,13 +2100,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_
 	transformed_glyphs[i] = glyphs[i];
 	_cairo_gstate_user_to_backend (gstate,
 				       &transformed_glyphs[i].x, 
 				       &transformed_glyphs[i].y);
     }
 
-    if (_cairo_operator_bounded (gstate->operator))
+    if (_cairo_operator_bounded (gstate->op))
 	status = _cairo_scaled_font_glyph_device_extents (gstate->scaled_font,
 							  transformed_glyphs, 
 							  num_glyphs, 
 							  &extents);
     else
 	status = _cairo_surface_get_extents (gstate->target, &extents);
@@ -2121,13 +2121,13 @@ _cairo_gstate_show_glyphs (cairo_gstate_
     _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
 
     glyph_info.font = gstate->scaled_font;
     glyph_info.glyphs = transformed_glyphs;
     glyph_info.num_glyphs = num_glyphs;
     
-    status = _cairo_gstate_clip_and_composite (&gstate->clip, gstate->operator,
+    status = _cairo_gstate_clip_and_composite (&gstate->clip, gstate->op,
 					       &pattern.base,
 					       _cairo_gstate_show_glyphs_draw_func, &glyph_info,
 					       gstate->target,
 					       &extents);
 
     _cairo_pattern_fini (&pattern.base);
Index: src/cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.214
diff -p -u -6 -r1.214 cairoint.h
--- src/cairoint.h	10 Oct 2005 19:45:15 -0000	1.214
+++ src/cairoint.h	10 Oct 2005 21:58:13 -0000
@@ -63,12 +63,14 @@
 #include <stdio.h>
 
 #include "cairo.h"
 #include "cairo-debug.h"
 #include <pixman.h>
 
+CAIRO_BEGIN_DECLS
+
 #if __GNUC__ >= 3 && defined(__ELF__)
 # define slim_hidden_proto(name)	slim_hidden_proto1(name, INT_##name)
 # define slim_hidden_def(name)		slim_hidden_def1(name, INT_##name)
 # define slim_hidden_proto1(name, internal)				\
   extern __typeof (name) name						\
 	__asm__ (slim_hidden_asmname (internal))			\
@@ -246,13 +259,17 @@ typedef enum cairo_int_status {
 typedef enum cairo_direction {
     CAIRO_DIRECTION_FORWARD,
     CAIRO_DIRECTION_REVERSE
 } cairo_direction_t;
 
 typedef struct _cairo_path_fixed cairo_path_fixed_t;
-typedef enum _cairo_clip_mode cairo_clip_mode_t;
+typedef enum _cairo_clip_mode {
+    CAIRO_CLIP_MODE_PATH,
+    CAIRO_CLIP_MODE_REGION,
+    CAIRO_CLIP_MODE_MASK
+} cairo_clip_mode_t;
 typedef struct _cairo_clip_path cairo_clip_path_t;
 typedef struct _cairo_clip cairo_clip_t;
 
 typedef struct _cairo_edge {
     cairo_line_t edge;
     int clockWise;
@@ -505,13 +522,13 @@ struct _cairo_scaled_font_backend {
     
     unsigned long
     (*ucs4_to_index)		(void			     *scaled_font,
 				 uint32_t		      ucs4);
     cairo_int_status_t
     (*show_glyphs)	(void			*scaled_font,
-			 cairo_operator_t	 operator,
+			 cairo_operator_t	 op,
 			 cairo_pattern_t	*pattern,
 			 cairo_surface_t	*surface,
 			 int			 source_x,
 			 int			 source_y,
 			 int			 dest_x,
 			 int			 dest_y,
@@ -594,13 +611,13 @@ struct _cairo_surface_backend {
     (*clone_similar)            (void                   *surface,
 				 cairo_surface_t        *src,
 				 cairo_surface_t       **clone_out);
 				 
     /* XXX: dst should be the first argument for consistency */
     cairo_int_status_t
-    (*composite)		(cairo_operator_t	 operator,
+    (*composite)		(cairo_operator_t	 op,
 				 cairo_pattern_t       	*src,
 				 cairo_pattern_t	*mask,
 				 void			*dst,
 				 int			 src_x,
 				 int			 src_y,
 				 int			 mask_x,
@@ -609,20 +626,20 @@ struct _cairo_surface_backend {
 				 int			 dst_y,
 				 unsigned int		 width,
 				 unsigned int		 height);
 
     cairo_int_status_t
     (*fill_rectangles)		(void			*surface,
-				 cairo_operator_t	 operator,
+				 cairo_operator_t	 op,
 				 const cairo_color_t	*color,
 				 cairo_rectangle_t	*rects,
 				 int			 num_rects);
 
     /* XXX: dst should be the first argument for consistency */
     cairo_int_status_t
-    (*composite_trapezoids)	(cairo_operator_t	 operator,
+    (*composite_trapezoids)	(cairo_operator_t	 op,
 				 cairo_pattern_t	*pattern,
 				 void			*dst,
 				 cairo_antialias_t	 antialias,
 				 int			 src_x,
 				 int			 src_y,
 				 int			 dst_x,
@@ -694,26 +711,26 @@ struct _cairo_surface_backend {
      * This is an optional entry to let the surface manage its own glyph
      * resources. If null, render against this surface, using image
      * surfaces as glyphs. 
      */    
     cairo_int_status_t 
     (*show_glyphs)		(cairo_scaled_font_t	        *font,
-				 cairo_operator_t		 operator,
+				 cairo_operator_t		 op,
 				 cairo_pattern_t		*pattern,
 				 void				*surface,
 				 int				 source_x,
 				 int				 source_y,
 				 int				 dest_x,
 				 int				 dest_y,
 				 unsigned int			 width,
 				 unsigned int			 height,
 				 const cairo_glyph_t		*glyphs,
 				 int				 num_glyphs);
 
     cairo_int_status_t
-    (*fill_path)		(cairo_operator_t	operator,
+    (*fill_path)		(cairo_operator_t	op,
  				 cairo_pattern_t	*pattern,
  				 void			*dst,
  				 cairo_path_fixed_t	*path,
 				 cairo_fill_rule_t	fill_rule,
 				 double			tolerance);
    
@@ -1009,13 +1026,13 @@ cairo_private cairo_status_t
 _cairo_gstate_set_source (cairo_gstate_t *gstate, cairo_pattern_t *source);
 
 cairo_private cairo_pattern_t *
 _cairo_gstate_get_source (cairo_gstate_t *gstate);
 
 cairo_private cairo_status_t
-_cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t operator);
+_cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t op);
 
 cairo_private cairo_operator_t
 _cairo_gstate_get_operator (cairo_gstate_t *gstate);
 
 cairo_private cairo_status_t
 _cairo_gstate_set_tolerance (cairo_gstate_t *gstate, double tolerance);
@@ -1217,13 +1234,13 @@ cairo_private cairo_status_t
 _cairo_gstate_glyph_path (cairo_gstate_t     *gstate, 
 			  cairo_glyph_t	     *glyphs, 
 			  int		      num_glyphs,
 			  cairo_path_fixed_t *path);
 
 cairo_private cairo_bool_t
-_cairo_operator_bounded (cairo_operator_t operator);
+_cairo_operator_bounded (cairo_operator_t op);
 
 /* cairo_color.c */
 cairo_private const cairo_color_t *
 _cairo_stock_color (cairo_stock_t stock);
 
 #define CAIRO_COLOR_WHITE       _cairo_stock_color (CAIRO_STOCK_WHITE)
@@ -1437,13 +1454,13 @@ _cairo_scaled_font_glyph_device_extents 
 					 const cairo_glyph_t	*glyphs,
 					 int                     num_glyphs,
 					 cairo_rectangle_t	*extents);
 
 cairo_private cairo_status_t
 _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
-				cairo_operator_t     operator,
+				cairo_operator_t     op,
 				cairo_pattern_t	    *source,
 				cairo_surface_t	    *surface,
 				int		     source_x,
 				int		     source_y,
 				int		     dest_x,
 				int		     dest_y,
@@ -1506,13 +1523,13 @@ _cairo_surface_init (cairo_surface_t			*
 		     const cairo_surface_backend_t	*backend);
 
 cairo_private cairo_clip_mode_t
 _cairo_surface_get_clip_mode (cairo_surface_t *surface);
 
 cairo_private cairo_status_t
-_cairo_surface_composite (cairo_operator_t	operator,
+_cairo_surface_composite (cairo_operator_t	op,
 			  cairo_pattern_t	*src,
 			  cairo_pattern_t	*mask,
 			  cairo_surface_t	*dst,
 			  int			src_x,
 			  int			src_y,
 			  int			mask_x,
@@ -1521,42 +1538,42 @@ _cairo_surface_composite (cairo_operator
 			  int			dst_y,
 			  unsigned int		width,
 			  unsigned int		height);
 
 cairo_private cairo_status_t
 _cairo_surface_fill_rectangle (cairo_surface_t	   *surface,
-			       cairo_operator_t	    operator,
+			       cairo_operator_t	    op,
 			       const cairo_color_t *color,
 			       int		    x,
 			       int		    y,
 			       int		    width,
 			       int		    height);
 
 cairo_private cairo_status_t
 _cairo_surface_fill_region (cairo_surface_t	   *surface,
-			    cairo_operator_t	    operator,
+			    cairo_operator_t	    op,
 			    const cairo_color_t    *color,
 			    pixman_region16_t      *region);
 
 cairo_private cairo_status_t
 _cairo_surface_fill_rectangles (cairo_surface_t		*surface,
-				cairo_operator_t	operator,
+				cairo_operator_t	op,
 				const cairo_color_t	*color,
 				cairo_rectangle_t	*rects,
 				int			num_rects);
 
 cairo_private cairo_int_status_t
-_cairo_surface_fill_path (cairo_operator_t	operator,
+_cairo_surface_fill_path (cairo_operator_t	op,
 			  cairo_pattern_t	*pattern,
 			  cairo_surface_t	*dst,
 			  cairo_path_fixed_t	*path,
 			  cairo_fill_rule_t	fill_rule,
 			  double		tolerance);
   
 cairo_private cairo_status_t
-_cairo_surface_composite_trapezoids (cairo_operator_t	operator,
+_cairo_surface_composite_trapezoids (cairo_operator_t	op,
 				     cairo_pattern_t	*pattern,
 				     cairo_surface_t	*dst,
 				     cairo_antialias_t	antialias,
 				     int		src_x,
 				     int		src_y,
 				     int		dst_x,
@@ -1565,13 +1582,13 @@ _cairo_surface_composite_trapezoids (cai
 				     unsigned int	height,
 				     cairo_trapezoid_t	*traps,
 				     int		ntraps);
 
 cairo_private cairo_status_t
 _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src,
-					      cairo_operator_t operator,
+					      cairo_operator_t op,
 					      cairo_surface_t *dst,
 					      cairo_traps_t *traps,
 					      cairo_clip_t *clip,
 					      cairo_antialias_t antialias);
 
 cairo_private cairo_status_t
@@ -1636,13 +1653,13 @@ _cairo_surface_set_clip (cairo_surface_t
 cairo_private cairo_status_t
 _cairo_surface_get_extents (cairo_surface_t   *surface,
 			    cairo_rectangle_t *rectangle);
 
 cairo_private cairo_status_t
 _cairo_surface_show_glyphs (cairo_scaled_font_t	        *scaled_font,
-			    cairo_operator_t		operator,
+			    cairo_operator_t		op,
 			    cairo_pattern_t		*pattern,
 			    cairo_surface_t		*surface,
 			    int				source_x,
 			    int				source_y,
 			    int				dest_x,
 			    int				dest_y,
@@ -2021,7 +2038,9 @@ slim_hidden_proto(cairo_new_path)
 slim_hidden_proto(cairo_rel_line_to)
 slim_hidden_proto(cairo_restore)
 slim_hidden_proto(cairo_save)
 slim_hidden_proto(cairo_stroke_preserve)
 slim_hidden_proto(cairo_surface_destroy)
 
+CAIRO_END_DECLS
+
 #endif


More information about the cairo mailing list