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); AutoLockView locker(surface->view); if (!locker) { _cairo_error(CAIRO_STATUS_NO_MEMORY); 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 (!*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 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_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( dst); 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; 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; } fprintf(stderr, "Composite\n"); // Draw it on screen. surface->view->PushState(); // If our image rect is only a subrect of the desired size, and we // aren't using B_OP_ALPHA, then we need to fill the rect first. if (mode == B_OP_COPY && !bmp->Bounds().Contains(srcRect)) { rgb_color black = { 0, 0, 0, 0 }; surface->view->SetDrawingMode(mode); surface->view->SetHighColor(black); surface->view->FillRect(dstRect); } if (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_status_t _cairo_beos_surface_acquire_dest_image (void *abstract_surface, cairo_rectangle_int16_t *interest_rect, cairo_image_surface_t **image_out, cairo_rectangle_int16_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_SUCCESS; } if (surface->bitmap) { surface->view->Sync(); *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap); if (!*image_out) 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) 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) return CAIRO_STATUS_NO_MEMORY; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; }