summaryrefslogtreecommitdiff
path: root/Build/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp')
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp984
1 files changed, 0 insertions, 984 deletions
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp b/Build/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp
deleted file mode 100644
index c97641685fc..00000000000
--- a/Build/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp
+++ /dev/null
@@ -1,984 +0,0 @@
-/* vim:set ts=8 sw=4 noet cin: */
-/* cairo - a vector graphics library with display and print output
- *
- * Copyright © 2005 Christian Biesinger <cbiesinger@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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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@web.de>
- *
- * Contributor(s):
- */
-
-// This is a C++ file in order to use the C++ BeOS API
-
-#include "cairoint.h"
-
-#include "cairo-beos.h"
-
-#include "cairo-error-private.h"
-#include "cairo-image-surface-inline.h"
-
-#include <new>
-
-#include <Bitmap.h>
-#include <Region.h>
-#if 0
-#include <DirectWindow.h>
-#endif
-#include <Screen.h>
-#include <Window.h>
-#include <Locker.h>
-
-/**
- * SECTION:beos-surface
- * @Title: BeOS Surfaces
- * @Short_Description: BeOS surface support
- * @See_Also: #cairo_surface_t
- *
- * The BeOS surface is used to render cairo graphics to BeOS views
- * and bitmaps.
- **/
-
-#define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)(CAIRO_STATUS_SUCCESS)
-
-struct cairo_beos_surface_t {
- cairo_surface_t base;
-
- cairo_region_t *clip_region;
-
- 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;
-
- // If true, surface and view should be deleted when this surface is
- // destroyed
- bool owns_bitmap_view;
-};
-
-class AutoLockView {
- public:
- AutoLockView(BView* view) : mView(view) {
- mOK = mView->LockLooper();
- }
-
- ~AutoLockView() {
- if (mOK)
- mView->UnlockLooper();
- }
-
- operator bool() {
- return mOK;
- }
-
- private:
- BView* mView;
- bool mOK;
-};
-
-static cairo_surface_t *
-_cairo_beos_surface_create_internal (BView* view,
- BBitmap* bmp,
- bool owns_bitmap_view = false);
-
-static inline BRect
-_cairo_rectangle_to_brect (const cairo_rectangle_int_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 inline cairo_rectangle_int_t
-_brect_to_cairo_rectangle (const BRect &rect)
-{
- cairo_rectangle_int_t retval;
- retval.x = floor (rect.left);
- retval.y = floor (rect.top);
- retval.width = ceil (rect.right) - retval.x + 1;
- retval.height = ceil (rect.bottom) - rectval.y + 1;
- return retval;
-}
-
-static inline 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
-};
-
-/**
- * _cairo_beos_view_to_bitmap:
- * @bitmap: [out] The resulting bitmap.
- * @rect: [out] The rectangle that was copied, in the view's coordinate system
- * @interestRect: If non-null, only this part of the view will be copied (view's coord system).
- *
- * Gets the contents of the view as a BBitmap*. Caller must delete the bitmap.
- **/
-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;
-}
-
-static void
-unpremultiply_bgra (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 ++) {
- uint8_t *b = &out[4*i];
- uint32_t pixel;
- uint8_t alpha;
-
- memcpy (&pixel, &data[4*i], sizeof (uint32_t));
- alpha = pixel & 0xff;
- if (alpha == 0) {
- b[0] = b[1] = b[2] = b[3] = 0;
- } else {
- b[0] = (((pixel >> 24) & 0xff) * 255 + alpha / 2) / alpha;
- b[1] = (((pixel >> 16) & 0xff) * 255 + alpha / 2) / alpha;
- b[2] = (((pixel >> 8) & 0xff) * 255 + alpha / 2) / alpha;
- b[3] = alpha;
- }
- }
- }
-}
-
-static inline int
-multiply_alpha (int alpha, int color)
-{
- int temp = (alpha * color) + 0x80;
- return ((temp + (temp >> 8)) >> 8);
-}
-
-static unsigned char*
-premultiply_bgra (unsigned char* data,
- int width,
- int height,
- int stride)
-{
- uint8_t * retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride));
- if (!retdata)
- return NULL;
-
- uint8_t * end = data + stride * height;
- for (uint8_t * in = data, *out = retdata;
- in < end;
- in += stride, out += stride)
- {
- for (int i = 0; i < width; i ++) {
- uint8_t *base = &in[4*i];
- uint8_t alpha = base[3];
- uint32_t p;
-
- if (alpha == 0) {
- p = 0;
- } else {
- uint8_t blue = base[0];
- uint8_t green = base[1];
- uint8_t red = base[2];
-
- if (alpha != 0xff) {
- blue = multiply_alpha (alpha, blue);
- green = multiply_alpha (alpha, green);
- red = multiply_alpha (alpha, red);
- }
- p = (alpha << 0) | (red << 8) | (green << 16) | (blue << 24);
- }
- memcpy (&out[4*i], &p, sizeof (uint32_t));
- }
- }
- return retdata;
-}
-
-static cairo_int_status_t
-_cairo_beos_surface_set_clip_region (cairo_beos_surface_t *surface,
- cairo_region_t *region)
-{
- cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
- abstract_surface);
- AutoLockView locker(surface->view);
- assert (locker);
-
- if (region == surface->clip_region)
- return CAIRO_INT_STATUS_SUCCESS;
-
- cairo_region_destroy (surface->clip_region);
- surface->clip_region = cairo_region_reference (region);
-
- if (region == NULL) {
- // No clipping
- surface->view->ConstrainClippingRegion(NULL);
- return CAIRO_INT_STATUS_SUCCESS;
- }
-
- int count = cairo_region_num_rectangles (region);
- BRegion bregion;
- for (int i = 0; i < count; ++i) {
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (region, i, &rect);
- // Have to subtract one, because for pixman, the second coordinate
- // lies outside the rectangle.
- bregion.Include (_cairo_rectangle_to_brect (&rect));
- }
- surface->view->ConstrainClippingRegion(&bregion);
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-
-/**
- * _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_bgra (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 _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
- 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;
-}
-
-/**
- * _cairo_image_surface_to_bitmap:
- *
- * 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_bgra (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:
- assert(0);
- return NULL;
- }
-}
-
-/**
- * _cairo_op_to_be_op:
- *
- * 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:
- // Does not actually work
- // XXX This is a fundamental compositing operator, it has to work!
-#if 1
- return false;
-#else
- *beos_op = B_OP_ADD;
- return true;
-#endif
-
- 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_surface_t *
-_cairo_beos_surface_create_similar (void *abstract_surface,
- cairo_content_t content,
- int width,
- int height)
-{
- 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:
- return NULL;
- 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_NOT_REACHED;
- 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)
-{
- 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;
- }
-
- cairo_region_destroy (surface->clip_region);
-
- 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)
-{
- cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
- abstract_surface);
- AutoLockView locker(surface->view);
- if (!locker)
- 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 (unlikely ((*image_out)->base.status))
- return (*image_out)->base.status;
-
- *image_extra = NULL;
- return CAIRO_STATUS_SUCCESS;
- }
-
- BBitmap* bmp;
- if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK)
- return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE
-
- *image_out = _cairo_beos_bitmap_to_surface (bmp);
- if (unlikely ((*image_out)->base.status)) {
- delete bmp;
- return (*image_out)->base.status;
- }
- *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);
-
- if (image_extra != NULL) {
- BBitmap* bmp = static_cast<BBitmap*>(image_extra);
- delete bmp;
- }
-}
-
-static cairo_status_t
-_cairo_beos_surface_acquire_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *interest_rect,
- cairo_image_surface_t **image_out,
- cairo_rectangle_int_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_t) CAIRO_INT_STATUS_NOTHING_TO_DO;
- }
-
- if (surface->bitmap) {
- surface->view->Sync();
- *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
- if (unlikely ((*image_out)->base.status))
- return (*image_out)->base.status;
-
- 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_rectangle_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_rectangle(rect);
- *image_out = _cairo_beos_bitmap_to_surface(bitmap);
- delete bitmap;
- if (unlikely ((*image_out)->base.status))
- return (*image_out)->base.status;
-
- *image_extra = NULL;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-
-static void
-_cairo_beos_surface_release_dest_image (void *abstract_surface,
- cairo_rectangle_int_t *intersect_rect,
- cairo_image_surface_t *image,
- cairo_rectangle_int_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)
- return;
-
- BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image);
- surface->view->PushState();
-
- surface->view->SetDrawingMode(B_OP_COPY);
-
- surface->view->DrawBitmap (bitmap_to_draw,
- _cairo_rectangle_to_brect (image_rect));
-
- surface->view->PopState();
-
- delete bitmap_to_draw;
- cairo_surface_destroy(&image->base);
-}
-
-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_region_t *clip_region)
-{
- cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
- dst);
- cairo_int_status_t status;
- 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;
-
- status = _cairo_beos_surface_set_clip_region (surface, clip_region);
- if (unlikely (status))
- return status;
-
- 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;
- }
-
- // 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_int_status_t
-_cairo_beos_surface_fill_rectangles (void *abstract_surface,
- cairo_operator_t op,
- const cairo_color_t *color,
- cairo_rectangle_int_t *rects,
- int num_rects,
- cairo_region_t *clip_region)
-{
- cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
- abstract_surface);
- cairo_int_status_t status;
-
- 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;
-
- status = _cairo_beos_surface_set_clip_region (surface, clip_region);
- if (unlikely (status))
- return status;
-
- 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 = color->red_short >> 8;
- be_color.green = color->green_short >> 8;
- be_color.blue = color->blue_short >> 8;
- }
-
- 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)
- surface->view->FillRect (_cairo_rectangle_to_brect (&rects[i]));
-
- surface->view->PopState();
-
- return CAIRO_INT_STATUS_SUCCESS;
-}
-
-static cairo_bool_t
-_cairo_beos_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int_t *rectangle)
-{
- cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
- abstract_surface);
- AutoLockView locker(surface->view);
- if (!locker)
- return FALSE;
-
- *rectangle = _brect_to_cairo_rectangle (surface->view->Bounds());
- return TRUE;
-}
-
-static const struct _cairo_surface_backend cairo_beos_surface_backend = {
- CAIRO_SURFACE_TYPE_BEOS,
- _cairo_beos_surface_create_similar,
- _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 */
- _cairo_beos_surface_composite, /* composite */
- _cairo_beos_surface_fill_rectangles,
- NULL, /* composite_trapezoids */
- NULL, /* create_span_renderer */
- NULL, /* check_span_renderer */
- NULL, /* copy_page */
- NULL, /* show_page */
- _cairo_beos_surface_get_extents,
- NULL, /* old_show_glyphs */
- NULL, /* get_font_options */
- NULL, /* flush */
- NULL, /* mark_dirty_rectangle */
- NULL, /* scaled_font_fini */
- NULL, /* scaled_glyph_fini */
-
- NULL, /* paint */
- NULL, /* mask */
- NULL, /* stroke */
- NULL, /* fill */
- 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_content_t content = CAIRO_CONTENT_COLOR;
- if (bmp && (bmp->ColorSpace() == B_RGBA32 || bmp->ColorSpace() == B_RGBA15))
- content = CAIRO_CONTENT_COLOR_ALPHA;
- _cairo_surface_init (&surface->base,
- &cairo_beos_surface_backend,
- NULL, /* device */
- content);
-
- surface->view = view;
- surface->bitmap = bmp;
- surface->owns_bitmap_view = owns_bitmap_view;
-
- surface->clip_region = NULL;
-
- return &surface->base;
-}
-
-/**
- * cairo_beos_surface_create:
- * @view: The view to draw on
- *
- * Creates a Cairo surface that draws onto a BeOS BView.
- * The caller must ensure that the view does not get deleted before the surface.
- * If the view is attached to a bitmap rather than an on-screen window, use
- * cairo_beos_surface_create_for_bitmap() instead of this function.
- *
- * Since: TBD
- **/
-cairo_surface_t *
-cairo_beos_surface_create (BView* view)
-{
- return cairo_beos_surface_create_for_bitmap(view, NULL);
-}
-
-/**
- * cairo_beos_surface_create_for_bitmap:
- * @view: The view to draw on
- * @bmp: The bitmap to which the view is attached
- *
- * 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.
- *
- * Since: TBD
- **/
-cairo_surface_t *
-cairo_beos_surface_create_for_bitmap (BView* view,
- BBitmap* bmp)
-{
- return _cairo_beos_surface_create_internal(view, bmp);
-}