summaryrefslogtreecommitdiff
path: root/src/cairo-beos-surface.cpp
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-07-23 15:32:13 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-07-23 15:32:14 +0100
commitbed2701e1c89095878d549cbca8f22d84f3dda3c (patch)
tree974807761b6d839839ecad9961eae8d567898dcc /src/cairo-beos-surface.cpp
parentf5a1cdf283a6aa1f4409ccbf3c2274fb587724fe (diff)
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of the operation state, is cumbersome and a hindrance to providing true proxy surface support. For example, the clip must be copied from the surface onto the fallback image, but this was forgotten causing undue hassle in each backend. Another example is the contortion the meta surface endures to ensure the clip is correctly recorded. By contrast passing the clip along with the operation is quite simple and enables us to write generic handlers for providing surface wrappers. (And in the future, we should be able to write more esoteric wrappers, e.g. automatic 2x FSAA, trivially.) In brief, instead of the surface automatically applying the clip before calling the backend, the backend can call into a generic helper to apply clipping. For raster surfaces, clip regions are handled automatically as part of the composite interface. For vector surfaces, a clip helper is introduced to replay and callback into an intersect_clip_path() function as necessary. Whilst this is not primarily a performance related change (the change should just move the computation of the clip from the moment it is applied by the user to the moment it is required by the backend), it is important to track any potential regression: ppc: Speedups ======== image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup ▌ image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup ▎ image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup ▏ image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup ▏ Slowdowns ========= image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown ▏
Diffstat (limited to 'src/cairo-beos-surface.cpp')
-rw-r--r--src/cairo-beos-surface.cpp409
1 files changed, 196 insertions, 213 deletions
diff --git a/src/cairo-beos-surface.cpp b/src/cairo-beos-surface.cpp
index e527272e..6fbdc470 100644
--- a/src/cairo-beos-surface.cpp
+++ b/src/cairo-beos-surface.cpp
@@ -56,6 +56,8 @@
struct cairo_beos_surface_t {
cairo_surface_t base;
+ cairo_region_t *clip_region;
+
BView* view;
/*
@@ -70,7 +72,6 @@ struct cairo_beos_surface_t {
BBitmap* bitmap;
-
// If true, surface and view should be deleted when this surface is
// destroyed
bool owns_bitmap_view;
@@ -101,27 +102,28 @@ _cairo_beos_surface_create_internal (BView* view,
BBitmap* bmp,
bool owns_bitmap_view = false);
-static BRect
-_cairo_rect_to_brect (const cairo_rectangle_int16_t* rect)
+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);
+ return BRect (rect->x, rect->y,
+ rect->x + rect->width - 1,
+ rect->y + rect->height - 1);
}
-static cairo_rectangle_int16_t
-_brect_to_cairo_rect (const BRect& rect)
+static inline cairo_rectangle_int_t
+_brect_to_cairo_rectangle (const BRect &rect)
{
- cairo_rectangle_int16_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;
+ 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 rgb_color
-_cairo_color_to_be_color (const cairo_color_t* color)
+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;
@@ -199,32 +201,8 @@ _cairo_beos_view_to_bitmap (BView* view,
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;
-}
-
-/**
- * unpremultiply_rgba:
- *
- * Takes an input in ABGR premultiplied image data and unmultiplies it.
- * The result is stored in retdata.
- **/
static void
-unpremultiply_rgba (unsigned char* data,
+unpremultiply_bgra (unsigned char* data,
int width,
int height,
int stride,
@@ -235,52 +213,108 @@ unpremultiply_rgba (unsigned char* data,
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
+ 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;
+ }
}
}
}
-/**
- * premultiply_rgba:
- *
- * Takes an input in ABGR non-premultiplied image data and premultiplies it.
- * The returned data must be freed with free().
- **/
+static inline int
+multiply_alpha (int alpha, int color)
+{
+ int temp = (alpha * color) + 0x80;
+ return ((temp + (temp >> 8)) >> 8);
+}
+
static unsigned char*
-premultiply_rgba (unsigned char* data,
+premultiply_bgra (unsigned char* data,
int width,
int height,
int stride)
{
- unsigned char* retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride));
+ uint8_t * retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride));
if (!retdata)
return NULL;
- unsigned char* end = data + stride * height;
- for (unsigned char* in = data, *out = retdata;
+ 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) {
- // 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
+ 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 substract 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:
*
@@ -309,8 +343,8 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap)
return imgsurf;
}
- cairo_format_t cformat = format == B_RGB32 ? CAIRO_FORMAT_RGB24
- : CAIRO_FORMAT_ARGB32;
+ 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());
@@ -318,8 +352,8 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap)
int height = bounds.IntegerHeight() + 1;
unsigned char* premultiplied;
if (cformat == CAIRO_FORMAT_ARGB32) {
- premultiplied = premultiply_rgba(bits, width, height,
- bitmap->BytesPerRow());
+ premultiplied = premultiply_bgra (bits, width, height,
+ bitmap->BytesPerRow());
} else {
premultiplied = reinterpret_cast<unsigned char*>(
_cairo_malloc_ab(bitmap->BytesPerRow(), height));
@@ -327,7 +361,7 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap)
memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);
}
if (!premultiplied)
- return NULL;
+ 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,
@@ -355,11 +389,11 @@ _cairo_image_surface_to_bitmap (cairo_image_surface_t* surface)
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()));
+ unpremultiply_bgra (surface->data,
+ surface->width,
+ surface->height,
+ surface->stride,
+ reinterpret_cast<unsigned char*>(data->Bits()));
return data;
}
case CAIRO_FORMAT_RGB24: {
@@ -384,44 +418,44 @@ _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
+ 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;
+ return false;
#else
- *beos_op = B_OP_ADD;
- return true;
+ *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_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_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_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:
+ case CAIRO_OPERATOR_XOR:
+ case CAIRO_OPERATOR_SATURATE:
- default:
- return false;
- };
+ default:
+ return false;
+ }
}
static cairo_surface_t *
@@ -430,8 +464,6 @@ _cairo_beos_surface_create_similar (void *abstract_surface,
int width,
int height)
{
- fprintf(stderr, "Creating similar\n");
-
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
@@ -444,9 +476,7 @@ _cairo_beos_surface_create_similar (void *abstract_surface,
BBitmap* bmp;
switch (content) {
case CAIRO_CONTENT_ALPHA:
- // Can't support this natively
- return _cairo_image_surface_create_with_content(content, width,
- height);
+ return NULL;
case CAIRO_CONTENT_COLOR_ALPHA:
bmp = new BBitmap(rect, B_RGBA32, true);
break;
@@ -470,10 +500,9 @@ _cairo_beos_surface_create_similar (void *abstract_surface,
}
break;
default:
- assert(0);
+ 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);
@@ -495,6 +524,8 @@ _cairo_beos_surface_finish (void *abstract_surface)
surface->bitmap = NULL;
}
+ cairo_region_destroy (surface->clip_region);
+
return CAIRO_STATUS_SUCCESS;
}
@@ -503,7 +534,6 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa
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);
AutoLockView locker(surface->view);
@@ -514,9 +544,9 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa
surface->view->Sync();
if (surface->bitmap) {
- *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
- if (!*image_out)
- return CAIRO_STATUS_NO_MEMORY;
+ *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;
@@ -526,10 +556,10 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa
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 (!*image_out) {
+ *image_out = _cairo_beos_bitmap_to_surface (bmp);
+ if (unlikely ((*image_out)->base.status)) {
delete bmp;
- return CAIRO_STATUS_NO_MEMORY;
+ return (*image_out)->base.status;
}
*image_extra = bmp;
@@ -543,17 +573,17 @@ _cairo_beos_surface_release_source_image (void *abstract_surfac
{
cairo_surface_destroy (&image->base);
- BBitmap* bmp = static_cast<BBitmap*>(image_extra);
- delete bmp;
+ 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_int16_t *interest_rect,
+ cairo_rectangle_int_t *interest_rect,
cairo_image_surface_t **image_out,
- cairo_rectangle_int16_t *image_rect,
+ cairo_rectangle_int_t *image_rect,
void **image_extra)
{
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
@@ -563,14 +593,14 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
if (!locker) {
*image_out = NULL;
*image_extra = NULL;
- return CAIRO_STATUS_SUCCESS;
+ 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 (!*image_out)
- return CAIRO_STATUS_NO_MEMORY;
+ if (unlikely ((*image_out)->base.status))
+ return (*image_out)->base.status;
image_rect->x = 0;
image_rect->y = 0;
@@ -581,7 +611,7 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
- BRect b_interest_rect(_cairo_rect_to_brect(interest_rect));
+ BRect b_interest_rect (_cairo_rectangle_to_brect (interest_rect));
BRect rect;
BBitmap* bitmap;
@@ -595,18 +625,11 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
if (status == ERROR)
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_rect = _brect_to_cairo_rectangle(rect);
*image_out = _cairo_beos_bitmap_to_surface(bitmap);
delete bitmap;
- if (!*image_out)
- return CAIRO_STATUS_NO_MEMORY;
+ if (unlikely ((*image_out)->base.status))
+ return (*image_out)->base.status;
*image_extra = NULL;
@@ -616,13 +639,11 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
static void
_cairo_beos_surface_release_dest_image (void *abstract_surface,
- cairo_rectangle_int16_t *intersect_rect,
+ cairo_rectangle_int_t *intersect_rect,
cairo_image_surface_t *image,
- cairo_rectangle_int16_t *image_rect,
+ cairo_rectangle_int_t *image_rect,
void *image_extra)
{
- fprintf(stderr, "Fallback drawing\n");
-
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
abstract_surface);
@@ -634,9 +655,9 @@ _cairo_beos_surface_release_dest_image (void *abstract_surface,
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->DrawBitmap (bitmap_to_draw,
+ _cairo_rectangle_to_brect (image_rect));
surface->view->PopState();
@@ -649,17 +670,19 @@ _cairo_beos_surface_composite (cairo_operator_t op,
cairo_pattern_t *src,
cairo_pattern_t *mask,
void *dst,
- int src_x,
+ int src_x,
int src_y,
int mask_x,
int mask_y,
int dst_x,
int dst_y,
unsigned int width,
- unsigned int height)
+ 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;
@@ -684,6 +707,10 @@ _cairo_beos_surface_composite (cairo_operator_t op,
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,
@@ -731,8 +758,6 @@ _cairo_beos_surface_composite (cairo_operator_t op,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
- fprintf(stderr, "Composite\n");
-
// Draw it on screen.
surface->view->PushState();
@@ -767,24 +792,17 @@ _cairo_beos_surface_composite (cairo_operator_t op,
}
-static void
-_cairo_beos_surface_fill_rectangle (cairo_beos_surface_t *surface,
- cairo_rectangle_int16_t *rect)
-{
- BRect brect(_cairo_rect_to_brect(rect));
- surface->view->FillRect(brect);
-}
-
static cairo_int_status_t
_cairo_beos_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
const cairo_color_t *color,
- cairo_rectangle_int16_t *rects,
- int num_rects)
+ cairo_rectangle_int_t *rects,
+ int num_rects,
+ cairo_region_t *clip_region)
{
- fprintf(stderr, "Drawing %i rectangles\n", num_rects);
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;
@@ -797,6 +815,10 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface,
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)
@@ -808,9 +830,9 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface,
if (mode == B_OP_COPY && be_color.alpha != 0xFF &&
(!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32))
{
- be_color.red = premultiply(be_color.red, be_color.alpha);
- be_color.green = premultiply(be_color.green, be_color.alpha);
- be_color.blue = premultiply(be_color.blue, be_color.alpha);
+ be_color.red = color->red_short >> 8;
+ be_color.green = color->green_short >> 8;
+ be_color.blue = color->blue_short >> 8;
}
surface->view->PushState();
@@ -822,65 +844,26 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface,
else
surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
- for (int i = 0; i < num_rects; ++i) {
- _cairo_beos_surface_fill_rectangle(surface, &rects[i]);
- }
+ 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_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);
- AutoLockView locker(surface->view);
- if (!locker)
- return CAIRO_INT_STATUS_SUCCESS;
-
- 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
+static cairo_bool_t
_cairo_beos_surface_get_extents (void *abstract_surface,
- cairo_rectangle_int16_t *rectangle)
+ 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 CAIRO_INT_STATUS_UNSUPPORTED;
-
- BRect size = surface->view->Bounds();
-
- *rectangle = _brect_to_cairo_rect(size);
+ return FALSE;
- // Make sure to have our upperleft edge as (0,0)
- rectangle->x = 0;
- rectangle->y = 0;
-
- return CAIRO_INT_STATUS_SUCCESS;
+ *rectangle = _brect_to_cairo_rectangle (surface->view->Bounds());
+ return TRUE;
}
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
@@ -899,8 +882,6 @@ static const struct _cairo_surface_backend cairo_beos_surface_backend = {
NULL, /* check_span_renderer */
NULL, /* copy_page */
NULL, /* show_page */
- _cairo_beos_surface_set_clip_region,
- NULL, /* intersect_clip_path */
_cairo_beos_surface_get_extents,
NULL, /* old_show_glyphs */
NULL, /* get_font_options */
@@ -938,7 +919,9 @@ _cairo_beos_surface_create_internal (BView* view,
surface->bitmap = bmp;
surface->owns_bitmap_view = owns_bitmap_view;
- return (cairo_surface_t *) surface;
+ surface->clip_region = NULL;
+
+ return &surface->base;
}
/**